c# - WPF DataGrid 禁用的单元格正在接收文本输入

标签 c# wpf datagrid isenabled datagridcell

考虑以下具有三列的 DataGrid:

enter image description here

当年龄为 -1 时,相应的单元格将被禁用。

理想情况下,用户不能更改禁用的单元格值。然而,考虑到用户在第 1 行,键盘焦点在 Age 列的相应单元格中,然后按回车键,现在用户键入任意数字,禁用的单元格得到该值!这是期望的行为吗?我怎样才能避免这种行为?

enter image description here

复制问题:

  1. 选择年龄列第 1 行的单元格
  2. 按回车键
  3. 输入一个数字

可重现的代码:

XAML:

<Window x:Class="wpf_behaviour.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridDetailsSample" Height="200" Width="400">
    <Grid Margin="10">
        <DataGrid Name="dgUsers" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}">
                    <DataGridTextColumn.CellStyle>
                        <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Age}" Value="-1">
                                    <Setter Property="IsEnabled" Value="False"/>
                                    <Setter Property="ToolTip" Value="This filed is diabled."/>
                                    <Setter Property="Background" Value="LightGray"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGridTextColumn.CellStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

对应的cs:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;

namespace wpf_behaviour
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<User> users = new List<User>();
            users.Add(new User() { Id = 1, Name = "Kumar", Age = 10 });
            users.Add(new User() { Id = 2, Name = "Sameer", Age = -1 });
            users.Add(new User() { Id = 3, Name = "Danny", Age= 16 });

            dgUsers.ItemsSource = users;
        }

        public class User
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }
}

最佳答案

我得到了解决方案(添加了 PreviewKeyDown 事件处理程序),就在这里,我也想知道任何更好的解决方案:

private void DataGridCell_PreviewKeyDown(object sender, KeyEventArgs e)
{
    try
    {
        DataGridCell cl = (DataGridCell)sender;
        //Get the Cell's parent row
        //using System.Windows.Media; for VisaualTreeHelper 
        var DataGridRowParent = VisualTreeHelper.GetParent(cl);
        while (DataGridRowParent != null && DataGridRowParent.GetType() != typeof(DataGridRow))
        {
            DataGridRowParent = VisualTreeHelper.GetParent(DataGridRowParent);
        }
        //Get the Row's parent DataGrid
        var DataGridParent = VisualTreeHelper.GetParent(DataGridRowParent);
        while (DataGridParent != null && DataGridParent.GetType() != typeof(DataGrid))
        {
            DataGridParent = VisualTreeHelper.GetParent(DataGridParent);
        }

        DataGrid dp = DataGridParent as DataGrid;
        //Get the CurrentCell value of DataGrid
        DataGridCellInfo cli = dp.CurrentCell;

        var CellContent = cli.Column.GetCellContent(cli.Item);
        if (CellContent != null)
        {
            //Get DataGridCell of DataGridCellInfo
            DataGridCell dgc = (DataGridCell)CellContent.Parent;
            if (dgc.IsEnabled == false)
            {
                //If the key pressed is Enter or Tab allow
                if (e.Key == Key.Enter || e.Key == Key.Tab)
                {
                    e.Handled = false;
                    return;
                }
                //If any other key is pressed don't allow.
                e.Handled = true;
                return;
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

关于c# - WPF DataGrid 禁用的单元格正在接收文本输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39975298/

相关文章:

c# - 如何将 async/await 与返回 ObservableCollection<T> 的方法一起使用

c# - 更改 System.Windows.Forms.DataGrid 中特定行的字体

wpf - 为 WPF Datagrid 或 DevexGridcontrol 生成动态列并动态绑定(bind)数据

c# - 如何使用用户输入的日期比较可为空类型的日期?

在对象字段中设置枚举的 C# DataContractSerializer SerializationException

c# - FakeItEasy - 让接口(interface)假继承自抽象,同时共享相同的接口(interface)继承

c# - 在 wpf 中创建一个无限居中的轮播控件

c# - 在不可聚焦的控件上执行某些操作时强制绑定(bind)更新

wpf - 如何从 View 到 View 模型交流OpenFileDialog结果 “FilePath”?

datagrid - 用户疯了! Wijmo Grid AfterCellUpdate 未触发