如何将自定义UserControl按钮点击绑定到父ViewModel的命令
问题描述
我有一个包含按钮、标签和文本框的自定义UserControl,该控件在MVVM模式的View中使用,希望将自定义控件的点击事件绑定到ViewModel中的命令。
现有代码如下:
View代码
public partial class ViewPage : UserControl { public ViewPage() { InitializeComponent(); } private void CustomControl_RestartClick(object sender, RoutedEventArgs e) { Debug.WriteLine("clicked"); } }
自定义UserControl代码
public partial class CustomControl : UserControl { public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(CustomControl), new PropertyMetadata(String.Empty)); public string Title { get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } public static readonly RoutedEvent RestartClickEvent = EventManager.RegisterRoutedEvent(nameof(RestartClick), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CustomControl)); public event RoutedEventHandler RestartClick { add { AddHandler(RestartClickEvent, value); } remove { RemoveHandler(RestartClickEvent, value); } } public CustomControl() { InitializeComponent(); } public void OnRestartClick(object sender, RoutedEventArgs e) { RaiseEvent(new RoutedEventArgs(RestartClickEvent)); } }
ViewModel中的命令
public ICommand RestartCommand { get; private set; }
期望实现的绑定写法:
<views:CustomControl Title="PS04-04" RestartClick="{Binding RestartCommand}" />
解决方案
WPF中无法直接将事件绑定到命令,以下是两种可行方案:
方案一:给自定义UserControl添加命令依赖属性(推荐)
直接在自定义控件中新增命令属性,将内部按钮点击与命令关联,这样可以直接在XAML中绑定命令,符合MVVM设计。
修改自定义UserControl代码
- 添加命令依赖属性:
public static readonly DependencyProperty RestartCommandProperty = DependencyProperty.Register(nameof(RestartCommand), typeof(ICommand), typeof(CustomControl)); public ICommand RestartCommand { get { return (ICommand)GetValue(RestartCommandProperty); } set { SetValue(RestartCommandProperty, value); } }
- 修改内部按钮的点击事件(假设自定义控件内触发点击的按钮为
btnRestart),执行绑定的命令:
private void btnRestart_Click(object sender, RoutedEventArgs e) { // 执行绑定的命令 RestartCommand?.Execute(null); // 若需保留原有路由事件,可继续触发 RaiseEvent(new RoutedEventArgs(RestartClickEvent)); }
使用绑定
现在可以直接在XAML中绑定ViewModel的命令:
<views:CustomControl Title="PS04-04" RestartCommand="{Binding RestartCommand}" />
方案二:使用交互行为绑定事件到命令
如果不想修改自定义控件代码,可以借助交互行为实现事件转命令。
步骤
- 在XAML中添加交互命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
- 给自定义控件添加事件触发器,将
RestartClick事件绑定到ViewModel的命令:
<views:CustomControl Title="PS04-04"> <i:Interaction.Triggers> <i:EventTrigger EventName="RestartClick"> <i:InvokeCommandAction Command="{Binding RestartCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> </views:CustomControl>
注:需确保项目已引用
Microsoft.Xaml.Behaviors.Wpf包(可通过NuGet安装)
内容的提问来源于stack exchange,提问作者DuckQuackington
相关产品推荐
相关产品推荐

