1

Is there a way I can delete a selected row in DataGrid using delete key with fixed column?

I have used code with command.manager event but it didn't delete the row if i use key down event it executes but it didn't delete the row in data grid. Here is the code I have used:

<Window x:Class="datagridcheck.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="1336" Width="937">
    <Grid  Name="grid1" Margin="10,10,135,10">
        <DataGrid x:Name="dgUsers" SelectionMode="Single" SelectionUnit="CellOrRowHeader" CommandManager.PreviewExecuted="DriversDataGrid_PreviewDeleteCommandHandler"  Margin="174,0,346,0" GridLinesVisibility="None" MinColumnWidth="50" FontFamily="Times New Roman" HorizontalGridLinesBrush="#FFF70000" VerticalGridLinesBrush="#FF0017FF" RowBackground="#FFF5F2D4" FontSize="18" TextOptions.TextHintingMode="Animated" TextOptions.TextFormattingMode="Display" RowDetailsVisibilityMode="Visible" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Width="264" Height="483" IsSynchronizedWithCurrentItem="False" SelectedIndex="0" PreviewKeyDown="dgUsers_PreviewKeyDown"   >
                        <DataGrid.Columns>
                    <DataGridTextColumn Header="FoodName" Width="90" Binding="{Binding FoodName}" MinWidth="90" Foreground="#FFFB1005" FontFamily="Times New Roman"/>
                <DataGridTextColumn Header="Quantity" Width="90" Binding="{Binding Birthday}" MinWidth="90" Foreground="Red" FontFamily="Times New Roman" />
                <DataGridTextColumn Binding="{Binding Id}" ClipboardContentBinding="{x:Null}" Header="Price" MinWidth="90" Width="90"/>
                </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="Background" Value="LightBlue" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="Blue"/>
                            <Setter Property="Foreground" Value="White"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="443,378,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <WrapPanel Height="355" Margin="443,0,0,0" VerticalAlignment="Top" Name="wrap1" HorizontalAlignment="Left" Width="331">
            <WrapPanel Height="100" Width="100"/>
        </WrapPanel>
        <Button Content="Button" HorizontalAlignment="Left" Margin="443,428,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
                <GridView>
                    <GridViewColumn Header="FoodName" Binding="{Binding FoodName}"/>
                    <GridViewColumn Header="Birthday" />
                </GridView>
    </Grid>
</Window>


namespace datagridcheck
          {
           public partial class MainWindow : Window
              {
                  public MainWindow()
                  {
                      InitializeComponent();
                  }
                  int i = 0;
                  private void Button_Click(object sender, RoutedEventArgs e)
                  { 
                      Button bt = new Button();
                      bt.Name = "test";
                      bt.Content="eachtime"+ i.ToString();
                      bt.Width = 50;
                      bt.Height = 50;
                      i++;
                      wrap1.Children.Add(bt);
                      bt.Click += new RoutedEventHandler(this.bt_Click); 
                   }
                  void bt_Click(object sender, RoutedEventArgs e)
                {
                      Button buts = sender as Button;
                      dgUsers.Items.Add(new User() { Id = 1, FoodName = Convert.ToString(buts.Content), Birthday = Convert.ToString(buts.Name) });
                  }
                  private void DriversDataGrid_PreviewDeleteCommandHandler(object sender, ExecutedRoutedEventArgs e)
                          {
                              if (e.Command == DataGrid.DeleteCommand)
                              {
                                  if (!(MessageBox.Show("Are you sure you want to delete?", "Please confirm.", MessageBoxButton.YesNo) == MessageBoxResult.Yes))
                                  {
                                    e.Handled = true;
                                  }
                              }
                          }
               }
              public class User
              {
              public int Id { get; set; }
                      public string FoodName { get; set; }
                      public string Birthday { get; set; }
             }
      }

1 Answer 1

1

Quickly MVVM = Model(Data) + View(Screens) + ViewModel(Code+logic)

First XAML :

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="gd"  CanUserDeleteRows="False"  ItemsSource="{Binding DataVMs}" SelectedItem="{Binding SelectedItemInVM, Mode=TwoWay}" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True">

            <DataGrid.InputBindings>
                <KeyBinding Gesture="Delete" Key="Delete" Command="{Binding DeleteCommand, Mode=OneWay}"  CommandParameter="{Binding Path=SelectedItem, ElementName=gd, Mode=OneWay}"/>
            </DataGrid.InputBindings>

            <DataGrid.Columns>
                <DataGridTextColumn Header="One" Binding="{Binding Un}" />
                <DataGridTextColumn Header="Two" Binding="{Binding Deux}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

In code Behind of MainWindow add this, assuming DataViewModel wrapps your model:

 public MainWindow()
        {
            InitializeComponent();

            //Initialize DataContext with some Data
            var dataContext = new DataViewCollectionModel
            {
                DataVMs = new ObservableCollection<DataViewModel>()

            };
            dataContext.DataVMs.Add(new DataViewModel { Un = 1, Deux = 2 });
            dataContext.DataVMs.Add(new DataViewModel { Un = 10, Deux = 20 });
            dataContext.DataVMs.Add(new DataViewModel { Un = 100, Deux = 200 });

            //Assign
            DataContext = dataContext;
        }

Now create You ViewModels :

1) BindableObject handles the notifications, it's the base class of all Viewmodels:

 public class BindableObject : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

    }

DataViewCollectionModel is what you pass to the DataContext of your View (In this case MainWindow). it must notify changes. that's why it inherits BindableObject. and it has a list of DataViewModel.

class DataViewCollectionModel : BindableObject
{
    private ObservableCollection<DataViewModel> dataVMs;
    private DataViewModel selectedItemInVM;
    public ObservableCollection<DataViewModel> DataVMs
    {
        get { return dataVMs; }
        set
        {
            if (dataVMs != value)
            {
                dataVMs = value;
                NotifyPropertyChanged("DataVMs");
            }
        }
    }

    public DataViewModel SelectedItemInVM
    {
        get { return selectedItemInVM; }
        set
        {
            if (selectedItemInVM != value)
            {
                selectedItemInVM = value;
                NotifyPropertyChanged("SelectedItemInVM");
            }
        }
    }

    private RelayCommand<DataViewModel> deleteCommand;
    public RelayCommand<DataViewModel> DeleteCommand
    {
        get { return deleteCommand ?? (deleteCommand = new RelayCommand<DataViewModel>(d => Delete(d))); }
    }

    private void Delete(DataViewModel d)
    {
        DataVMs.Remove(selectedItemInVM);
    }

}

and finaly, your DataViewModel wich represents each row in the DataGrid.

 public class DataViewModel : BindableObject
    {

        public int Un { get; set; }
        public int Deux { get; set; }

    }

And as I am very friendly, I give you a helper that handles commands :

   public class RelayCommand<T> : ICommand
    {

        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;


        public RelayCommand(Action<T> execute)
            : this(execute, null)
        {
        }

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

            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute((T)parameter);
        }

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

        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }

    }

To test just click Delete key when you select a Row.

Hope it helps.

Sign up to request clarification or add additional context in comments.

5 Comments

how to use mvvm in my code. i am new to wpf. i'm directly add item to datagrid but when i use itemssource to bind datagrid it delete the row in datagrid
thanks but when i click a button i want to populate one row when i click another button i want to populate on second row.but in this i'm able to populate only one row but i'm able to delete it
like delete add command add. I can update my answer but upvote me please !
Sir Please Update How to use command add..i don't have reputation to vote u but my friend vote u
just question of time. give some time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.