Home > Software engineering >  In WPF, map click of MenuItem Edit->Undo to TextBox Ctrl-Z key
In WPF, map click of MenuItem Edit->Undo to TextBox Ctrl-Z key

Time:08-01

Let's Say I'm making a simple editor in WPF using a TextBox and a Menu with the option "Edit->Undo". My XML is as follows:

<Window x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel LastChildFill="True">
        <Menu Name="menu1" DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Name="menu1_edit_undo"   
                          Header="_Undo"   
                          InputGestureText="Ctrl Z"/>
            </MenuItem>
        </Menu>

        <Grid>
            <TextBox Name="textbox1"/>
        </Grid>
    </DockPanel>
    
</Window>

How do I get the Click event for "menu1_edit_undo" to send the Key Stroke "Ctrl-Z" to the TextBox component textbox1 to invoke the undo feature of the textbox?

HEre's what I tried that didn't work:

        private void menu1_edit_undo_Click(
           object sender, RoutedEventArgs e)
        {
            var e2 = new KeyEventArgs(
                keyboard: Keyboard.PrimaryDevice,
                inputSource: PresentationSource.FromVisual(textbox1),
                timestamp: 0,
                key: Key.LeftCtrl | Key.Z
            )
            {
                RoutedEvent= Keyboard.KeyDownEvent 
            };

            textbox1.RaiseEvent(e2);
        }

CodePudding user response:

Ok... I found out you can do it my adding a Reference to System.Windows.Form to you WPF project, and then adding this to the Click handler:

textbox1.Focus();
System.Windows.Form.SendKeys.SendWait("^z");

M$ why do you never finish things?

CodePudding user response:

The WPF TextBox has an Undo method (part of the TextBoxBase base class) that should provide what you need.

Undoes the most recent undo command. In other words, undoes the most recent undo unit on the undo stack.

Instead of attempting to send keystrokes to the control, just call the method on it:

        private void menu1_edit_undo_Click(
           object sender, RoutedEventArgs e)
        {
            textbox1.Undo();
        }
  • Related