如果我理解正确,您需要使用 Delete 键,而不是删除行,而是在它们上放置一个标记。
在 DataGrid 中,您需要突出显示用此标记标记的行的颜色。
你没有展示你的桌子,所以我将在我的简单调解中展示。
示例使用BaseInpc and RelayCommand classes。
除此之外,使用命令扩展方式:
using System.Windows.Input;
namespace Simplified
{
public static class CommandExtensionMethods
{
public static bool TryExecute(this ICommand command, object parameter)
{
bool can = command.CanExecute(parameter);
if (can)
command.Execute(parameter);
return can;
}
public static bool TryExecute(this ICommand command)
=> TryExecute(command, null);
}
}
视图模型:
using Simplified;
using System.Data;
using System.Windows.Input;
namespace DeferredRowDeletion
{
public class DrdViewModel : BaseInpc
{
public DataTable Table { get; } = new DataTable();
public DrdViewModel()
{
Table.Columns.Add("Name", typeof(string));
Table.Columns.Add("Value", typeof(int));
Table.Columns.Add("Marked for deletion", typeof(bool));
foreach (var name in new string[] { "First", "Second", "Third", "Fourth", "Fifth" })
{
var row = Table.NewRow();
row[0] = name;
row[1] = Table.Rows.Count;
row[2] = Table.Rows.Count % 2 == 1;
Table.Rows.Add(row);
}
}
private ICommand _markRemoveChangeCommand;
private bool _isRemoveRowsImmediately;
public ICommand MarkRemoveChangeCommand => _markRemoveChangeCommand
?? (_markRemoveChangeCommand = new RelayCommand<DataRow>(
row => row[2] = !(bool)(row[2] ?? false),
row => !IsRemoveRowsImmediately
));
public bool IsRemoveRowsImmediately
{
get => _isRemoveRowsImmediately;
set => Set(ref _isRemoveRowsImmediately, value);
}
}
}
窗口 XAML:
<Window x:Class="DeferredRowDeletion.DrdWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredRowDeletion"
mc:Ignorable="d"
Title="DrdWindow" Height="450" Width="800">
<FrameworkElement.DataContext>
<local:DrdViewModel/>
</FrameworkElement.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox Content="Removw Rows Immediately"
IsChecked="{Binding IsRemoveRowsImmediately}"
Margin="5"/>
<DataGrid x:Name="dataGrid" Grid.Row="1"
ItemsSource="{Binding Table, Mode=OneWay}"
AutoGeneratingColumn="OnAutoGeneratingColumn"
CanUserDeleteRows="{Binding IsRemoveRowsImmediately}"
PreviewKeyDown="OnPreviewKeyDown">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding [Marked for deletion]}" Value="true">
<Setter Property="Background" Value="HotPink"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
</Window>
窗口后面的代码:
using Simplified;
using System.Data;
using System.Windows;
using System.Windows.Input;
namespace DeferredRowDeletion
{
public partial class DrdWindow : Window
{
public DrdWindow()
{
InitializeComponent();
}
private void OnAutoGeneratingColumn(object sender, System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName == "Marked for deletion")
e.Cancel = true;
}
private void OnPreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
DrdViewModel viewModel = (DrdViewModel)DataContext;
var rowView = dataGrid.CurrentItem as DataRowView;
if (rowView != null && !rowView.IsEdit)
viewModel.MarkRemoveChangeCommand.TryExecute(rowView.Row);
}
}
}
}
如果您无法使用此示例,请写下原因并在问题解释中添加详细信息。
答案由补充细节的说明补充:
我想我应该提到我使用绑定到 DataTrigger 的 DataRow 的 RowState 属性来更新行背景颜色。为问题添加了详细信息。
要控制行的可见性,您需要更改DataTable.DefaultView.RowStateFilter 属性的值。
这在 ViewModel 中并不难做到。
但另一个问题是RowState 属性没有通知其更改。
所以触发器绑定不会像那样工作。
在我的示例中,我通过调用Items.Refresh () 解决了这个问题。
也许您正在使用不同的解决方案,因为您没有写过任何与此相关的问题。
using Simplified;
using System.Data;
using System.Windows.Input;
namespace DeferredRowDeletion
{
public class ShowDeletedRowsViewModel : BaseInpc
{
public DataTable Table { get; } = new DataTable();
public ShowDeletedRowsViewModel()
{
Table.Columns.Add("Name", typeof(string));
Table.Columns.Add("Value", typeof(int));
foreach (var name in new string[] { "First", "Second", "Third", "Fourth", "Fifth" })
{
var row = Table.NewRow();
row[0] = name;
row[1] = Table.Rows.Count;
Table.Rows.Add(row);
}
// Commits all the changes
Table.AcceptChanges();
Table.Rows[1].Delete();
Table.Rows[3].Delete();
// Show Deleded Rows
IsVisibilityDelededRows = true;
}
private ICommand _markRemoveChangeCommand;
private bool _isVisibilityDelededRows;
public ICommand MarkRemoveChangeCommand => _markRemoveChangeCommand
?? (_markRemoveChangeCommand = new RelayCommand<DataRow>(
row => IsVisibilityDelededRows ^= true,
row => !IsVisibilityDelededRows
));
public bool IsVisibilityDelededRows
{
get => _isVisibilityDelededRows;
set => Set(ref _isVisibilityDelededRows, value);
}
protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue)
{
base.OnPropertyChanged(propertyName, oldValue, newValue);
if (propertyName == nameof(IsVisibilityDelededRows))
{
// Change the row filter if the associated property has changed
if (IsVisibilityDelededRows)
{
Table.DefaultView.RowStateFilter |= DataViewRowState.Deleted;
}
else
{
Table.DefaultView.RowStateFilter &= ~DataViewRowState.Deleted;
}
}
}
}
}
<Window x:Class="DeferredRowDeletion.SdrWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredRowDeletion" xmlns:data="clr-namespace:System.Data;assembly=System.Data"
mc:Ignorable="d"
Title="SdrWindow" Height="450" Width="800">
<FrameworkElement.DataContext>
<local:ShowDeletedRowsViewModel/>
</FrameworkElement.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel>
<CheckBox x:Name="cbAutoRefresh" Content="Auto Items.Refresh()" IsChecked="True" Margin="5"/>
<CheckBox Content="Visibility Deleded Rows"
IsChecked="{Binding IsVisibilityDelededRows}"
Margin="5"/>
</StackPanel>
<DataGrid x:Name="dataGrid" Grid.Row="1"
ItemsSource="{Binding Table, Mode=OneWay}"
PreviewKeyUp="OnPreviewKeyUp">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Row.RowState, Mode=OneWay}"
Header="RowState"/>
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Row.RowState}" Value="{x:Static data:DataRowState.Deleted}">
<Setter Property="Background" Value="HotPink"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
</Window>
private void OnPreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete && cbAutoRefresh.IsChecked == true)
dataGrid.Items.Refresh();
}