我正在关注Josh Smith 的 Design 解释 WPF + MVVM。我几乎和他的演示应用程序有相同的要求。我必须将他的 CustomerViewModel 类中的保存命令分配给主窗口中的工具栏按钮。
是否可以通过 XAML 或仅通过代码隐藏以及如何实现?
谢谢
我正在关注Josh Smith 的 Design 解释 WPF + MVVM。我几乎和他的演示应用程序有相同的要求。我必须将他的 CustomerViewModel 类中的保存命令分配给主窗口中的工具栏按钮。
是否可以通过 XAML 或仅通过代码隐藏以及如何实现?
谢谢
你可以这样做:
<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>
谢谢你的回复,保罗。这就是我最终做的事情。正如我上面提到的,我使用的是 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 做到这一点,请随意分享?
谢谢
我知道我之前所做的一切都是一种解决方法,而且很脏。随着我对 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。