Search code examples
c#wpfmvvmuser-controls

How to bind custom UserControl button click to command to UCs parent viewModel


I have a custom control that contains buttons, labels and textboxes. This user control is being used in another View that has a ViewModel. I want to Bind the click event handler from the custom control to a command in the viewModel.

The code for the View:

    public partial class ViewPage : UserControl
    {
        public ViewPage()
        {
            InitializeComponent();
        }

        private void CustomControl_RestartClick(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("clicked");

        }
    }
}

The code for the custom user control:

public partial class CustomControl : UserControl
{

    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    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));
    }
}

I have this command in the ViewModel I want to bind it to:

public ICommand RestartCommand { get; private set; }

I want to be able to do somehtign like

<views:CustomControl Title="PS04-04"  RestartClick="{Binding RestartCommand}" />

link to github: https://github.com/MaganaLu/MCP_WPF.git


Solution

  • You need a dependency property that accepts an ICommand.

    public static readonly DependencyProperty FooCommandProperty =
      DependencyProperty.Register(nameof(FooCommand), typeof(ICommand), typeof(CustomControl));
    
    public ICommand FooCommand
    {
      get => (ICommand)GetValue(FooCommandProperty);
      set => SetValue(FooCommandProperty, value);
    }
    

    Then somewhere in your user control (probably in an event handler) you need to Execute that command when something happens.

    if(FooCommand != null && FooCommand.CanExecute(fooParameter))
    {
      FooCommand.Execute(fooParameter);
    }
    

    Once you have all that in place, you just bind your ICommand to the property.