【发布时间】:2011-07-07 23:30:46
【问题描述】:
我有一个在 ContentControl 中加载用户控件的父窗口。父窗口有一个带有一些按钮的工具栏(即保存按钮)。我想分配将在用户控件内处理的那些按钮命令。
我需要从用户控件的 ViewModel 管理我自己的 ICommand 命令,因此总结一下:用户单击“保存”按钮(在主窗口上),因此该按钮会触发用户控件处理的事件以保存其中的信息控件。
这可能吗?
【问题讨论】:
我有一个在 ContentControl 中加载用户控件的父窗口。父窗口有一个带有一些按钮的工具栏(即保存按钮)。我想分配将在用户控件内处理的那些按钮命令。
我需要从用户控件的 ViewModel 管理我自己的 ICommand 命令,因此总结一下:用户单击“保存”按钮(在主窗口上),因此该按钮会触发用户控件处理的事件以保存其中的信息控件。
这可能吗?
【问题讨论】:
有两种方法。
使用 MVVM,
由于您的窗口包含 UserControl,因此您需要进行设置,以便 Window 具有对 UserControl ViewModel 的引用(假设它被称为 UserControlViewModel)。如果您在 UserControlViewModel 中有一个命令,则可以通过调用以下命令绑定到该命令: UserControlViewModel.Command 类似:
<Button x:Name="Save" Content="Save" Command="{Binding UserControlViewModel.SaveCommand}">
使用事件处理程序
同样,您的窗口需要有对实现事件处理程序的类的引用。您可以在 Window XAML 文件中包含以下内容:
<Button x:Name="Save" Content="Save" Clicked="SaveButtonClicked"/>
然后在你的代码后面,
private void SaveButtonClicked( .... sender, .... e)
{
UserControlClass.SaveData();
// or using command
UserControlClass.MyCommand.Execute()
}
【讨论】:
好的,您正在尝试将子元素的命令绑定到父窗口。首先为用户控件命名(例如 x:Name = MyUserControl)并在用户控件的 datacontext/viewmodel 中编写公共命令(例如 ICommand MyCommand)。现在在按钮中执行此操作
<Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} />
这会将保存按钮命令绑定到子用户控件的数据上下文中的命令:)
顺便说一句,如果您正在寻找其他方式(即将子命令绑定到 mvvm 中的父级),您将需要使用 FindAncestor。你可以看看我的codeproject article 关于这个:)
【讨论】:
这听起来像是路由命令可以工作的情况。对于路由命令,将收费栏按钮的命令设置为“保存”。然后在用户控件中,添加一个监听“保存”命令的命令绑定。
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.CommandBindings>
<CommandBinding
Command="Save"
CanExecute="SaveCommand_CanExecute"
Executed="SaveCommand_Executed"
/>
</UserControl.CommandBindings>
</UserControl>
在命令绑定的代码隐藏事件处理程序中,只需找到视图模型并在其视图模型上调用保存命令。如果你想要更纯粹的 MVVM 方法,你可以试试Josh Smith's approach to routed commands with MVVM。
使用这种方法,只要用户控件在其中某处有焦点,那么保存按钮的保存命令将路由到用户控件的命令绑定并执行保存命令。
我认为这可能会实现您将工具栏按钮与 ContentPresenter 中动态加载的用户控件分离的目标。
【讨论】:
过了一会儿,我回到这个问题。我需要与我的父窗口进行通信,所以我决定直接从父窗口执行 view-viewmodel 数据上下文绑定,主要是因为我希望子视图模型附加到从其父窗口触发的事件,并且我可以向父窗口触发事件为了显示子控件之外的消息。
我知道我可能没有完全使用 MVVM 模式,但我想更好地控制这些功能。
【讨论】: