【问题标题】:Accessing ICommands from MainWindow : Josh Smith's Article从 MainWindow 访问 ICommands:Josh Smith 的文章
【发布时间】:2011-08-01 20:49:32
【问题描述】:

我关注Josh Smith's Design explaining WPF + MVVM。我几乎和他的演示应用程序有相同的要求。我必须将他的 CustomerViewModel 类中的保存命令分配给主窗口中的工具栏按钮。

是否可以通过 XAML 或仅通过代码隐藏以及如何实现?

谢谢

【问题讨论】:

    标签: wpf mvvm icommand mainwindow


    【解决方案1】:

    你可以这样做:

    <Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
        <MenuItem Header="File">
            <MenuItem Header="Save" Command="Save"/>
        </MenuItem>
    </Menu>
    

    我很确定这会调用默认的保存方法,但如果你想定义一个自定义保存方法,你可以这样做:

    <Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
        <MenuItem Header="File">
            <MenuItem Header="Save" Command="{Binding Path="CustomSaveCommand"}"/>
        </MenuItem>
    </Menu>
    

    确保像这样向视图模型添加数据上下文引用

    <Window.DataContext>
        <my:MainWindowViewModel/>
    </Window.DataContext>
    

    【讨论】:

    • 是的,但这将调用主窗口的 CustomSaveCommand。我想调用 CustomerViewModel 的 CustomSaveCommand。
    • 然后只需将您的 DataContext 更改为您想要的任何内容。这只是一个示例,不一定 100% 适用于您的情况。
    【解决方案2】:

    感谢您的回复,保罗。这就是我最终要做的。 如前所述,我使用的是 Josh Smith 的设计,我想从 MainWindowViewModel 中调用CustomerViewModel 对象的Save() 方法(Command)。 因此,我在主窗口中将点击事件附加到我的工具栏按钮上。

    <Button Name="btnSaveAllWorkspaces" ToolTip="Save All Open Workspaces" Content="Save All" Click="OnSaveAllWorkspacesClicked"/>        
    

    然后在后面的代码中,

    private void OnSaveAllWorkspacesClicked(object sender, RoutedEventArgs e)
        {
            if (MainVM != null)
            {
                if (MainVM.Workspaces != null && MainVM.Workspaces.Count > 0)
                {
                    foreach (WorkspaceViewModel wkVM in MainVM.Workspaces)
                    {
                        CustomerViewModel vm = wkVM as CustomerViewModel;
                        if (vm != null)
                            vm.Save();
                    }
                }
            }
        }
    

    最初我只想保存当前活动的工作区,但后来我认为因为它是所有工作区顶部的全局按钮,所以保存所有打开的工作区是有意义的,因此foreach 循环。

    如果有更好的方法可以通过 XAML 来实现,请随时分享?

    谢谢

    【讨论】:

      【解决方案3】:

      我知道我之前所做的一切都是一种解决方法,而且很脏。随着我对 MVVM 的了解越来越多,我不断重构代码。这就是我所做的。

      为 MainWindowViewModel 上的 SaveCommand 添加了 ICommand Proerty,并将其绑定到主窗口上的工具按钮。它只是将调用委托给当前活动的 WorksSpaceViewModel 的 SaveCommand。

         public override ICommand SaveCommand
          {
              get
              {
                  return _currentWorkspace != null ? _currentWorkspace.SaveCommand : new RelayCommand ( null, param => false);
              }
          }
      

      和在原始代码中一样,它跟踪当前工作区,确保我通知子系统更改

          public ObservableCollection<WorkspaceViewModel> Workspaces
          {
              get
              {
                  if (_workspaces == null)
                  {
                      _workspaces = new ObservableCollection<WorkspaceViewModel>();
                      _workspaces.CollectionChanged += OnWorkspacesChanged;
                      CollectionViewSource.GetDefaultView(_workspaces).CurrentChanged += new EventHandler(MainWindowViewModel_CurrentChanged);
                  }
                  return _workspaces;
              }
          }
      
          private void MainWindowViewModel_CurrentChanged(object sender, EventArgs e)
          {
              CurrentWorkspace = CollectionViewSource.GetDefaultView(_workspaces).CurrentItem as WorkspaceViewModel;
              OnPropertyChanged("SaveCommand");
          }
      
          public WorkspaceViewModel CurrentWorkspace
          {
              get { return _currentWorkspace; }
              set
              {
                  _currentWorkspace = value;
                  OnPropertyChanged("CurrentWorkspace");
              }
          }
      

      就是这样,WPF 负责其余的工作(即,根据验证启用、禁用按钮)!

      再次感谢 Paul 的提示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-09
        相关资源
        最近更新 更多