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

时间:2016-10-11 10:29:24

标签: c# wpf datagrid isenabled datagridcell

考虑以下DataGrid有三列:

enter image description here

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

理想情况下,用户不可能更改禁用的单元格值。但是考虑用户在第1行并且键盘焦点位于列Age的相应单元格中,然后按Enter键,现在用户键入任何数字,禁用的单元格获得该值!这是一个理想的行为吗?我该如何避免这种行为?

enter image description here

要复制问题:

  1. 选择Age列<1 li>的第1行中的单元格
  2. 按enter
  3. 输入数字
  4. 可重复的代码:

    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>
    

    Correspoinding 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; }
            }
        }
    }
    

2 个答案:

答案 0 :(得分:0)

我不确定为什么会这么开心,但你可以抓住Enter Event并取消编辑:

C#

private void MyDataGrid_OnKeyDown(object sender, KeyEventArgs e)
{
    var dg = sender as DataGrid;

    // alter this condition for whatever valid keys you want - avoid arrows/tab, etc.
    if (dg != null && !dg.IsReadOnly && e.Key == Key.Enter)
    {
        dg.CancelEdit();
        e.Handled = true;
    }
}

XAML

<DataGrid Grid.Column="1" Name="dgUsers" AutoGenerateColumns="False" PreviewKeyDown="MyDataGrid_OnKeyDown">

答案 1 :(得分:0)

我得到了解决方案(添加了一个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());
    }
}