1

I've tried almost every solution on Stackoverflow I don't understand why my binding statement for button inside datagrid is not giving hit on the property in ViewModel. This is my DataGrid:

 <DataGridTemplateColumn Header="Delete">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Command="{Binding DataContext.DeleteButton, RelativeSource={RelativeSource AncestorType=UserControl}}">Delete</Button>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

And this is my Code in VeiwModel:

private ICommand _delete;

        public ICommand DeleteButton
        {
            get
            {
                if (_delete == null)
                {
                    _delete = new UserCommand(DeleteItemExecute, CanDeleteItemExecute);
                }
                return _delete;
            }
        }
Psychonaut007
  • 167
  • 3
  • 13

3 Answers3

0

I do the same thing, but another way :

View code :

<Button Click="DeleteObject">
    <Image Source="../img/image_delete.png" Width="20" Height="20"/>
</Button>

Then on my model :

private void DeleteObject(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    Object selectedObject = button.DataContext as Object;
}
Siegfried.V
  • 1,508
  • 1
  • 16
  • 34
0

Added "Name" to my reference

<Page x:Class="InventoryManagementWPF.Views.InventoryPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:InventoryManagementWPF.Views"
      xmlns:viewmodel ="clr-namespace:InventoryManagementWPF.ViewModel"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="InventoryPage"
  ------>    x:Name="_window">  <------------- Added this change only
<Button Command="{Binding DataContext.DeleteButton, ElementName=_window}" CommandParameter ="{Binding}">Delete</Button>

Else everything is the same. This worked for me. I found the solution here

ZF007
  • 3,708
  • 8
  • 29
  • 48
Psychonaut007
  • 167
  • 3
  • 13
0

You can do as follows without specifying a connector name.You can find detailed information about the use of RelativeSource here.

Xaml Code

   <DataGrid ItemsSource="{Binding DataItemCollection}" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item - 1" Binding="{Binding Item1}"/>
            <DataGridTextColumn Header="Item - 2" Binding="{Binding Item2}"/>
            <DataGridTextColumn Header="Item - 3" Binding="{Binding Item3}"/>
            <DataGridTemplateColumn Header="Delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.DeleteCommand}">Delete</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

ViewModeCode

class MainWindowViewModel
    {
        public RelayCommand DeleteCommand { get; set; }


        private ObservableCollection<DataItem> _dataItemCollection = new ObservableCollection<DataItem>();
        public ObservableCollection<DataItem> DataItemCollection
        {
            get { return _dataItemCollection; }
            set { _dataItemCollection = value; }
        }

        public MainWindowViewModel()
        {
            DataItemCollection.Add(new DataItem { Item1 = "Item - 1", Item2 = "Item - 2", Item3 = "Item - 3" });


            DeleteCommand = new RelayCommand(Delete);
        }

        void Delete(object param)
        {
            Console.WriteLine("Delete Click");
        }
    }

RelayCommand

public class RelayCommand : ICommand
{
    #region Fields
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion

    #region Constructors
    public RelayCommand(Action<object> execute) : this(execute, null) { }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion

    #region ICommand Members
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
    #endregion
}
Ozgur Saklanmaz
  • 528
  • 3
  • 17