WPF DataGrid实现输入0/1后自动提交值并跳转至下一可编辑单元格
完全可以实现,以下是分步骤的具体实现方案:
1. 配置DataGrid列的可编辑权限
先在XAML中明确指定各列的可编辑状态,ID和Total列设为只读,其他列允许编辑:
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" PreviewTextInput="DataGrid_PreviewTextInput" PreviewKeyDown="DataGrid_PreviewKeyDown"> <DataGrid.Columns> <DataGridTextColumn Header="ID" Binding="{Binding ID}" IsReadOnly="True"/> <DataGridTextColumn Header="Value1" Binding="{Binding Value1, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Value2" Binding="{Binding Value2, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Value3" Binding="{Binding Value3, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Value4" Binding="{Binding Value4, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Value5" Binding="{Binding Value5, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Total" Binding="{Binding Total}" IsReadOnly="True"/> </DataGrid.Columns> </DataGrid>
这里UpdateSourceTrigger=PropertyChanged确保输入值立即同步到数据源,方便实时计算Total。
2. 限制输入仅为0和1
通过PreviewTextInput过滤非法输入,同时处理粘贴操作防止非法内容进入:
private void DataGrid_PreviewTextInput(object sender, TextCompositionEventArgs e) { // 仅允许输入0或1 if (e.Text != "0" && e.Text != "1") { e.Handled = true; } } private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e) { // 拦截粘贴非法内容 if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { var clipboardContent = Clipboard.GetText(); if (!string.IsNullOrWhiteSpace(clipboardContent) && clipboardContent != "0" && clipboardContent != "1") { e.Handled = true; return; } } // 处理0/1按键的提交与跳转逻辑 if (e.Key is Key.D0 or Key.NumPad0 or Key.D1 or Key.NumPad1) { // 延迟执行确保输入值已写入单元格 Dispatcher.BeginInvoke(() => { dataGrid.CommitEdit(DataGridEditingUnit.Cell); MoveToNextEditableCell(); }, DispatcherPriority.Background); } }
3. 跳转至下一个可编辑单元格
实现MoveToNextEditableCell方法,按顺序查找当前单元格之后的第一个可编辑单元格,优先当前行的后续列,找不到则切换到下一行的第一个可编辑列:
private void MoveToNextEditableCell() { var currentCell = dataGrid.CurrentCell; int currentColIndex = dataGrid.Columns.IndexOf(currentCell.Column); int currentRowIndex = dataGrid.Items.IndexOf(currentCell.Item); // 查找当前行的下一个可编辑列 for (int col = currentColIndex + 1; col < dataGrid.Columns.Count; col++) { if (!dataGrid.Columns[col].IsReadOnly) { dataGrid.CurrentCell = new DataGridCellInfo(dataGrid.Items[currentRowIndex], dataGrid.Columns[col]); dataGrid.BeginEdit(); return; } } // 当前行无后续可编辑列,查找下一行的第一个可编辑列 for (int row = currentRowIndex + 1; row < dataGrid.Items.Count; row++) { for (int col = 0; col < dataGrid.Columns.Count; col++) { if (!dataGrid.Columns[col].IsReadOnly) { dataGrid.CurrentCell = new DataGridCellInfo(dataGrid.Items[row], dataGrid.Columns[col]); dataGrid.ScrollIntoView(dataGrid.Items[row], dataGrid.Columns[col]); dataGrid.BeginEdit(); return; } } } // 无更多可编辑单元格,结束编辑状态 dataGrid.CommitEdit(DataGridEditingUnit.Row); }
4. 实时计算Total列值
在数据实体类中实现INotifyPropertyChanged,当Value1-Value5变化时自动计算Total:
public class DataItem : INotifyPropertyChanged { private int _id; private int _value1; private int _value2; private int _value3; private int _value4; private int _value5; public int ID { get => _id; set { _id = value; OnPropertyChanged(); } } public int Value1 { get => _value1; set { _value1 = value; OnPropertyChanged(); CalculateTotal(); } } public int Value2 { get => _value2; set { _value2 = value; OnPropertyChanged(); CalculateTotal(); } } public int Value3 { get => _value3; set { _value3 = value; OnPropertyChanged(); CalculateTotal(); } } public int Value4 { get => _value4; set { _value4 = value; OnPropertyChanged(); CalculateTotal(); } } public int Value5 { get => _value5; set { _value5 = value; OnPropertyChanged(); CalculateTotal(); } } public int Total { get; private set; } private void CalculateTotal() { Total = Value1 + Value2 + Value3 + Value4 + Value5; OnPropertyChanged(nameof(Total)); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
内容的提问来源于stack exchange,提问作者user18107302
相关产品推荐
相关产品推荐

