2

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

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

谢谢

4

3 回答 3

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>

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

<Window.DataContext>
    <my:MainWindowViewModel/>
</Window.DataContext>
于 2011-08-01T21:02:03.553 回答
0

谢谢你的回复,保罗。这就是我最终做的事情。正如我上面提到的,我使用的是 Josh Smith 的设计,我想从 MainWindowViewModel 中调用对象的Save()方法(Command) 。CustomerViewModel因此,从主窗口中,我将单击事件附加到我的工具栏按钮,如下所示。

<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 做到这一点,请随意分享?

谢谢

于 2011-08-02T16:14:24.493 回答
0

我知道我之前所做的一切都是一种解决方法,而且很脏。随着我对 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。

于 2012-02-02T19:57:03.390 回答