Search code examples
c#wpfxamlbuttondatatemplate

DataTemplate button command from binding


I'm using Wpf and I'm passing a List<Value> to a <ItemsControl> in the xaml. I would like to bind the string in the Value Object to the Command of a Button. This xaml part looks like this:

    <Grid Margin="0,0,2,0">
    <Grid Margin="10">
        <ItemsControl Name="details">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,0,0,5">
                        <Grid.ColumnDefinitions>
                            ....
                        </Grid.ColumnDefinitions>
                        ...
                        <Button Grid.Column="2"
                                Content="{Binding ButtonContent}"
                                Visibility="{Binding ButtonVisibility}"
                                Command="{Binding ButtonClickMethod}" />
        ...

My Value Class looks like this:

public class Value
{        
    ...
    public string ButtonClickMethod { get; set; }

}

I'm setting the string link this:

v.ButtonClickMethod = "RelatedActivityId_OnClick";

And the Method is in the same class and looks like this:

private void RelatedActivityId_OnClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("RelatedActivityId_OnClick");
    }

Everything besides this is working properly and unses the same Object for the binding. What am I doing wrong?


Solution

  • The Command property of the Button is of type ICommand so you cannot bind it to a string value.

    You need to update your ButtonClickMethod to be of type ICommand or create a new property to bind you Command to.

    See this answer for a sample implementation of ICommand.

    If you need the button to execute code based on a parameter (string value?) then you can use the CommandParameter property, then use that paramters in your Command handler.

    public class Value
    {        
        public Value()
        {
            ButtonCommand  = new RelayCommand((a) => true, CommandMethod); 
        }
    
        public RelayCommand ButtonCommand {get; set; }
        public string ButtonClickMethod { get; set; }
    
        private void CommandMethod(object obj)
        {
            MessageBox.Show(obj?.ToString());
        }
    }
    

    and the XAML:

    <Button Grid.Column="2"
             Content="{Binding ButtonContent}"
             Visibility="{Binding ButtonVisibility}"
             Command="{Binding ButtonCommand}"
             CommandParameter="{Binding ButtonClickMethod}" />