You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:48:26