#621 – An Example of Handling Preview Keypress Events

Below is an example of handling both PreviewKeyUp and KeyUp events.  The PreviewKeyUp is used to completely block a particular key (the letter ‘E’).  The KeyUp event is used to trigger an update to a calculated property.

    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal"
                    PreviewKeyDown="StackPanel_PreviewKeyUp">
            <Label Content="First Name:" VerticalAlignment="Center"/>
            <TextBox Margin="5" Width="100" Height="25"
                     Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     KeyUp="txtFirst_KeyUp"/>
            <Label Content="Last Name:" VerticalAlignment="Center"/>
            <TextBox Margin="5" Width="100" Height="25"
                     Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     KeyUp="txtLast_KeyUp"/>
        </StackPanel>
        <Label Content="{Binding FullName}"/>
        <Label Content="{Binding LastChanged}"/>
    </StackPanel>

 

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public string FullName { get; set; }
        public string LastChanged { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            CalcFullName();
        }

        private void StackPanel_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            // E's are not allowed !
            if (e.Key == Key.E)
                e.Handled = true;
        }

        private void txtFirst_KeyUp(object sender, KeyEventArgs e)
        {
            CalcFullName();
            LastChanged = "Changing FIRST Name";
            RaisePropertyChanged("LastChanged");
        }

        private void txtLast_KeyUp(object sender, KeyEventArgs e)
        {
            CalcFullName();
            LastChanged = "Changing LAST Name";
            RaisePropertyChanged("LastChanged");
        }

        private void CalcFullName()
        {
            FullName = string.Format("Full Name: [{0} {1}]", FirstName, LastName);
            RaisePropertyChanged("FullName");
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }

    }

Advertisement

#620 – Why Are There So Many KeyPress Events?

When you press a single key within a WPF application, there are potentially a number of different keypress events that can fire.  But why are there so many different events that can possibly fire?

There are several reasons why there isn’t just a single keypress event.

  • Your application will only see the events for which you define a handler.  There is a large set of possible events so that you can choose which ones make sense for your application to handle.
  • Preview events exist so that a parent control can intercept keypress events for its children or descendants.  The tunneling allows you to decide at what level you want to preview the event.
  • The actual keypress event bubbles up the logical tree so that you can decide at what level to actually respond to the event.  In this way, you can handle multiple events in a single place.

#619 – Event Sequence for the Key Up/Down Events

There are four basic events related to a key being pressed or released that a GUI element can fire in WPF.  An event fires when you press a key down (KeyDown) and a different event fires when you release the key (KeyUp).  When these events fire for an element, they fire first for the element and then work back up the logical tree, firing for each ancestor element.  These are bubbling events.

There are also the PreviewKeyDown and PreviewKeyUp events, which fire before the KeyDown and KeyUp events, but fire from the top of the logical tree down to the control where the event originated.  (Tunneling events).

For a Window containing a StackPanel that contains a TextBox, the event sequence when a user presses a key while the TextBox has focus is:

  • Window_PreviewKeyDown
  • StackPanel_PreviewKeyDown
  • TextBox_PreviewKeyDown
  • TextBox_KeyDown
  • StackPanel_KeyDown
  • Window_KeyDown
  • Window_PreviewKeyUp
  • StackPanel_PreviewKeyUp
  • TextBox_PreviewKeyUp
  • TextBox_KeyUp
  • StackPanel_KeyUp
  • Window_KeyUp