Create, define, or generate a KeyDown / PreviewKeyDown event for DataGridTextColumn or DataGridCell in WPF

رضا جافری 1,296 Reputation points
2022-04-30T19:04:16.433+00:00

Hi
My project includes DataGrid, and I'd like to be able to control the type of user input.
197769-keydown.png
I defined a PreviewKeyDown event for DataGridTextColumn, but it does not work and gives me an error.

<DataGridTextColumn x:Name="DateOfBirth" Binding="{Binding DateOfBirth}" Keyboard.PreviewKeyDown="DateOfBirth_PreviewKeyDown" Width="SizeToHeader"/>  

Error: DateOfBirth_PreviewKeyDown is not valid. PreviewKeyDown is not an event on System.Windows.Controls.DataGridTextColumn. Line 1462 Position 155.
I tried other options as well, but I couldn't come to a conclusion.
In WPF, how do I define, create, or generate a KeyDown / PreviewKeyDown event for a DataGridTextColumn?

Thanks for your attention. I’m looking forward to your reply.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,777 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,933 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
809 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 48,536 Reputation points Microsoft Vendor
    2022-05-02T06:17:39.543+00:00

    If you want to restrict the type of input data for a particular column, you could try to refer to the code below.
    MainWindow.xaml:

      <Window.Resources>  
            <CollectionViewSource x:Key="CountryView" Source="{Binding Countries}"/>  
        </Window.Resources>  
        <Grid>  
            <DataGrid x:Name="dg" Width="200" Height="250" ItemsSource="{Binding Source={StaticResource CountryView}}"   
                      SelectedItem="{Binding SelectedCountry}"  AutoGenerateColumns="False">  
                <DataGrid.Columns>  
                    <DataGridTextColumn Header="name" Binding="{Binding Country}"/>  
                    <DataGridTemplateColumn Header="daten">  
                        <DataGridTemplateColumn.CellTemplate>  
                            <DataTemplate>  
                                <TextBlock Text="{Binding Daten}"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellTemplate>  
                        <DataGridTemplateColumn.CellEditingTemplate>  
                            <DataTemplate>  
                                <TextBox Text="{Binding  Daten}" PreviewKeyDown="TextBox_PreviewKeyDown"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellEditingTemplate>  
    
                    </DataGridTemplateColumn>  
                </DataGrid.Columns>  
    
            </DataGrid>  
        </Grid>  
    

    MainWindow.xaml.cs:

    using System;  
    using System.Collections.ObjectModel;  
    using System.Windows;  
    using System.Windows.Input;  
    
    namespace DataGridBindICollectionView  
    {  
      public partial class MainWindow : Window  
      {  
       ViewModel vm = new ViewModel();  
        public MainWindow()  
        {  
          InitializeComponent();  
          DataContext = vm;  
        }  
        private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)  
        {  
          if (e.Key != Key.D0 && e.Key != Key.D1 && e.Key != Key.D2 && e.Key != Key.D3 && e.Key != Key.D4 && e.Key != Key.D5 && e.Key != Key.D6 && e.Key != Key.D7 && e.Key != Key.D8 && e.Key != Key.D9 && e.Key != Key.Back && e.Key != Key.NumPad0 && e.Key != Key.NumPad1 && e.Key != Key.NumPad2 && e.Key != Key.NumPad3 && e.Key != Key.NumPad4 && e.Key != Key.NumPad5 && e.Key != Key.NumPad6 && e.Key != Key.NumPad7 && e.Key != Key.NumPad8 && e.Key != Key.NumPad9 && e.Key != Key.Delete && e.Key != Key.Right && e.Key != Key.Left)  
    
          {  
    
            e.Handled = true;  
    
          }  
          if (e.Key == Key.Space || e.Key == Key.Back)  
          {  
            e.Handled = true;  
          }  
        }  
      }  
      public class ViewModel  
      {  
        public ObservableCollection<MyCountry> Countries { get; set; }  
        public MyCountry SelectedCountry { get; set; }  
        public ViewModel()  
        {  
          Countries = new ObservableCollection<MyCountry>();  
          Countries.Add(new MyCountry() { Country = "Beijing", Daten = DateTime.Now });  
          Countries.Add(new MyCountry() { Country = "NewYork", Daten = DateTime.Now });  
          Countries.Add(new MyCountry() { Country = "Shanghai", Daten = DateTime.Now });  
        }  
      }  
      public class MyCountry  
      {  
        public string Country { get; set; }  
        public DateTime Daten { get;set;}  
      }  
    }  
    

    The result:
    You can only enter numbers, not characters.
    198112-3.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html

    1 person found this answer helpful.

  2. رضا جافری 1,296 Reputation points
    2022-05-03T16:11:02.433+00:00

    My solution is as follows:
    First: In XAML and C#, define the PreviewKeyDown and rename the Handler as follows.
    Create

    <DataGridTextColumn x:Name="DateTaken" Binding="{Binding DateTaken}" Width="SizeToHeader">  
     <DataGridTextColumn.CellStyle>  
        <Style TargetType="DataGridCell">  
            <EventSetter Event="PreviewKeyDown" Handler="DateTaken_PreviewKeyDown"/>  
        </Style>  
     </DataGridTextColumn.CellStyle>  
    </DataGridTextColumn>  
    

    Then in the PreviewKeyDown event (C#), you can set a limit.

        private void DateTaken_PreviewKeyDown(object sender, KeyEventArgs e)  
        {  
            switch (!((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9 || e.Key==Key.OemQuestion) || e.Key == Key.Back || e.Key == Key.Home || e.Key == Key.End || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Tab || Keyboard.Modifiers == ModifierKeys.Control))  
            {  
                case true:  
                    MessageBox.Show("Character " + e.Key.ToString() + " is not allowed", "Information", MessageBoxButton.OK, MessageBoxImage.Information);  
                    e.Handled = true;  
                    break;  
                default:  
                    switch (e.Key == Key.A || e.Key == Key.C || e.Key == Key.V || e.Key == Key.Y || e.Key == Key.Z)  
                    {  
                        case true:  
                            break;  
                    }  
                    break;  
            }  
        }  
    

    Output (tested in Visual Studio 2017, .Net Framework 4.5.2):
    Output

    Thanks

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.