WPF的DataGrid禁用小区接收文本输入

问题描述:

考虑有三列下面的DataGrid:WPF的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> 

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; } 
     } 
    } 
} 
+0

看看这个帖子http://*.com/questions/37584559/datagridcheckboxcolumn -loses-isreadonly-state-when-application-elementstyle –

+0

@ S.Akbari Setting '没有帮助! – Abbas

我不知道为什么这happaning但你可以赶上输入事件并取消编辑:

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"> 
+0

我不想取消所有的'Key.Enter'。并且正在接收谷值的禁用细胞的事件都没有被触发。所以我绝对没有办法找出接收文本的单元格是否为禁用单元格。 – Abbas

我得到的溶液(加了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()); 
    } 
}