如何使用固定列的删除键删除DataGrid中的选定行
How to delete selected row in DataGrid using delete key with fixed column
有没有一种方法可以使用固定列的删除键删除 DataGrid
中的选定行?
我使用了带有 command.manager 事件的代码,但如果我使用它执行的按键事件,它不会删除该行,但它不会删除数据网格中的行。这是我使用的代码:
<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; }
}
}
快速 MVVM = 模型(数据)+ 视图(屏幕)+ ViewModel(代码+逻辑)
第一个 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>
在 MainWindow 的代码后面添加这个,假设 DataViewModel 包装了您的模型:
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;
}
现在创建您的 ViewModel:
1) BindableObject 处理通知,它是所有视图模型的基础class:
public class BindableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
DataViewCollectionModel 是您传递给视图(在本例中为 MainWindow)的 DataContext 的内容。它必须通知更改。这就是它继承 BindableObject 的原因。它有一个 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);
}
}
最后,您的 DataViewModel 代表 DataGrid 中的每一行。
public class DataViewModel : BindableObject
{
public int Un { get; set; }
public int Deux { get; set; }
}
因为我很友好,所以我给你一个处理命令的助手:
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);
}
}
要进行测试,只需在 select 一行时单击 Delete 键。
希望对您有所帮助。
有没有一种方法可以使用固定列的删除键删除 DataGrid
中的选定行?
我使用了带有 command.manager 事件的代码,但如果我使用它执行的按键事件,它不会删除该行,但它不会删除数据网格中的行。这是我使用的代码:
<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; }
}
}
快速 MVVM = 模型(数据)+ 视图(屏幕)+ ViewModel(代码+逻辑)
第一个 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>
在 MainWindow 的代码后面添加这个,假设 DataViewModel 包装了您的模型:
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;
}
现在创建您的 ViewModel:
1) BindableObject 处理通知,它是所有视图模型的基础class:
public class BindableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
DataViewCollectionModel 是您传递给视图(在本例中为 MainWindow)的 DataContext 的内容。它必须通知更改。这就是它继承 BindableObject 的原因。它有一个 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);
}
}
最后,您的 DataViewModel 代表 DataGrid 中的每一行。
public class DataViewModel : BindableObject
{
public int Un { get; set; }
public int Deux { get; set; }
}
因为我很友好,所以我给你一个处理命令的助手:
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);
}
}
要进行测试,只需在 select 一行时单击 Delete 键。
希望对您有所帮助。