Search code examples
c#.netwpfmvvmdata-binding

Binding Property in command parameter (datagrid)


I have a data grid that lists information present in an observable collection. So far everything is working fine.

I would then like to add a stop command which Name property as a parameter but when i write CommandParameter= {Binding Name}, my button is disable. I try to set CommandParameter with a random string and that's working, so the probleme comes from the binding.

        <DataGrid.Columns>


            <DataGridTextColumn Header="Name" Binding="{ Binding Name }"/>
            <DataGridTextColumn Header="Source" Binding="{ Binding Source }"/>
            <DataGridTextColumn Header="Target" Binding="{ Binding Target }"/>

            <DataGridTemplateColumn Header="Stop">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Stop" 
                                Command="{ Binding DataContext.StopCommand, RelativeSource = { RelativeSource FindAncestor,AncestorType={ x:Type DataGrid } } }"                         
                                CommandParameter="{ Binding Name }"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

Thanks you !


Solution

  • I think that this problem is in your code-behind code. I have created an example for you and in this example, I'm using your XAML code.

    In this example, I'm using Prism.WPF NuGet package.

    XAML code:

    <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Source" Binding="{Binding Source}"/>
            <DataGridTextColumn Header="Target" Binding="{Binding Target}"/>
            <DataGridTemplateColumn Header="Stop">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Stop" 
                                Command="{Binding DataContext.StopCommand, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}}}"                         
                                CommandParameter="{Binding Name}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            </DataGrid.Columns>
    </DataGrid>
    

    Code-behind:

    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new FooViewModel();
        }
    }
    
    public class Foo
    {
        public string Name { get; set; }
    }
    
    public class FooViewModel : BindableBase
    {
        public FooViewModel()
        {
            for (int i = 0; i < 100; i++) Items.Add(new Foo() { Name = $"name_{i}" });
            StopCommand = new DelegateCommand<string>(OnStopCommand);
        }
    
        public ICommand StopCommand { get; private set; }
        public ObservableCollection<Foo> Items { get; set; } = new ObservableCollection<Foo>();
    
        private void OnStopCommand(string name) => Console.WriteLine(name);
    }