11

I have a WPF window which opens as a modal dialog.

On dialog, I have OK & Cancel buttons with IsDefault & IsCancel properties set to True for them respectively. Both the buttons have Click event handlers which close the dialog box.

Here is the relevant XAML:

<StackPanel Orientation="Horizontal" Grid.Row="1"  Height="45" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="190">
    <Button Content="OK"
                Height="25" Margin="10,10,10,10" Width="75" Name="btnOK" TabIndex="1600" IsDefault="True" Click="btnOK_Click"                       
                VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
    <Button Content="Cancel"
                Height="25" Margin="10,10,10,10" Width="75" Name="btnCancel" TabIndex="1700" IsCancel="True"
                VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Click="btnCancel_Click" />
</StackPanel>

Here is the code behind:

private void btnOK_Click(object sender, RoutedEventArgs e)
{
    // My some business logic is here                
    this.Close();
}

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

When I press Esc button on the keyboard (even when focus is not on the Cancel button), the dialog box gets closed as expected. However, when I press Enter key when focus is NOT on the OK button, nothing happens.

I have a DataGrid on the dialog. I want to close the dialog when I select any row in the data grid and press enter.

How to make this thing happen?

Some additional information: I have a text box on the dialog. And it has the event handler for the Keyboard.PreviewKeyDown event. When I am in the text box and I press enter, the dialog box should not be closed. But I can remove this handler. Important thing is to get above question resolved.

private void tbxSearchString_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        this.Search(); // Does some searching
    }
}
H.B.
  • 166,899
  • 29
  • 327
  • 400
Learner
  • 4,661
  • 9
  • 56
  • 102
  • 3
    What you encounter is the default and expected behavior, you should not change it. Further the way you handle the dialog is a bit exotic; normally you should only set the `DialogResult` to `true` or `false` in the event handlers of the buttons, and the logic should be done in the bit of code which opens the dialog, like this: `if ((bool)diag.ShowDialog()) { /*Here*/ }`. – H.B. Sep 22 '11 at 05:58
  • +1 cause H.B. is so fast... :) – blindmeis Sep 22 '11 at 06:24
  • +1 for pointing out correct way of coding (`DialogResult`)! :) – Learner Sep 22 '11 at 06:28

4 Answers4

9

Your code is working fine for me. it close dialog when I press enter. You can write e.Handled = true; line after your search functionality in tbxSearchString_PreviewKeyDown event. So it will not close dialog.

<Grid>
        <TextBox Name="tbxSearchString" HorizontalAlignment="Left" Width="100" Height="30" Grid.Row="0" PreviewKeyDown="tt_PreviewKeyDown"></TextBox>
        <StackPanel Orientation="Horizontal" Grid.Row="1"  Height="45" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="190">

            <Button Content="OK" 
                Height="25" Margin="10,10,10,10" Width="75" Name="btnOK" TabIndex="1600" IsDefault="True" Click="btnOK_Click"                        
                VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
            <Button Content="Cancel" 
                Height="25" Margin="10,10,10,10" Width="75" Name="btnCancel" TabIndex="1700" IsCancel="True" 
                VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Click="btnCancel_Click" />
        </StackPanel>
    </Grid>

Code behind

private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true; 
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void tbxSearchString_PreviewKeyDown(object sender, KeyEventArgs e)
        {
           if (e.Key == Key.Enter)
           {
               this.Search();
               e.Handled = true;
           }
        }
Upendra Chaudhari
  • 6,473
  • 5
  • 25
  • 42
  • 2
    +1 for `e.Handled = true`. However, `this.Close()` is not necessary when you are setting the `DisalogResult` property. – Learner Sep 22 '11 at 09:12
  • thanks for e.Handled = true - in my scenario the window closed with return-key and the event bubbled to the parent window which reopened the window ... ;) – Lumo Nov 27 '19 at 10:22
8

there is no built-in way to close the dialog window in wpf. what you have to do, is to set the DialogResult for your default button. so all you need is the following:

xaml

<Button Content="OK" 
            Height="25" Margin="10,10,10,10" Width="75" Name="btnOK" TabIndex="1600" IsDefault="True" Click="btnOK_Click"                        
            VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />

codebehind:

    private void btnOK_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
    }
blindmeis
  • 22,175
  • 7
  • 55
  • 74
  • The problem is not the closing though (`Close()` achieves that as well, even though it should not be used in dialogs) but the fact that the focus on the DataGrid prevents the Button from being pressed on Enter. – H.B. Sep 22 '11 at 06:35
7

You shouldn't be calling Close() or handling PreviewKeyDown yourself.

The proper way to do this is to have Ok/Cancel buttons, and use Button.IsDefault, Button.IsCancel, and Window.DialogResult. If the 'enter' press is unhandled in your textbox, the keypress will propagate to the Window and the default button will be pressed.


MyForm.xaml:

<Button x:Name="btnOk" Content="Ok" Click="btnOk_Click" IsDefault="True"/>
<Button x:Name="btnCancel" Content="Cancel" Click="btnCancel_Click" IsCancel="True"/>

MyForm.xaml.cs:

private void btnOk_Click(object sender, RoutedEventArgs e)
{
    DialogResult = true;
}

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
    DialogResult = false;
}

Now hitting enter or escape on any textbox in the form will close the form (with the proper result)

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • The TextBox will not update the Text Binding in default mode when the User presses Enter. One could use `UpdateSourceTrigger=PropertyChanged`to ensure that the Binding was updated before the Enter-Key handling. – Dennis Kuypers Jun 22 '17 at 04:04
0

Just set the AcceptButton member to the button property name.

AcceptButton = btnOK;   // button used when ENTER is pressed