我关注Josh Smith's Design explaining WPF + MVVM。我几乎和他的演示应用程序有相同的要求。我必须将CustomerViewModel类的Save命令分配给主窗口中的Toolbar按钮。
是否可以通过XAML或仅通过代码隐藏以及如何实现?
感谢
答案 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负责其余的事情(即根据验证启用,禁用按钮)!
再次感谢你的小费保罗。