从MainWindow访问ICommands:Josh Smith的文章

时间:2011-08-01 20:49:33

标签: wpf mvvm icommand mainwindow

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

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

感谢

3 个答案:

答案 0 :(得分:3)

你可以这样做:

<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>

确保向viewmodel添加一个datacontext引用,如下所示

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

答案 1 :(得分:0)

谢谢你的回复,保罗。这就是我最终做的事情。 正如我上面提到的,我正在使用Josh Smith的设计,我想从MainWindowViewModel调用Save()对象的CustomerViewModel方法(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做到这一点,请自由分享?

感谢

答案 2 :(得分:0)

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

在MainWindowViewModel上添加了ICommand Proerty for SaveCommand,并将其绑定到主窗口上的工具按钮。它只是将调用委托给当前活动的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负责其余的事情(即根据验证启用,禁用按钮)!

再次感谢你的小费保罗。