按下 Enter 键时如何关闭 WPF 窗口(对话框)?
Posted
技术标签:
【中文标题】按下 Enter 键时如何关闭 WPF 窗口(对话框)?【英文标题】:How to close WPF window (dialog box) when Enter key is pressed? 【发布时间】:2011-11-22 12:43:46 【问题描述】:我有一个 WPF window
,它作为模式对话框打开。
在对话框中,我有 OK
和 Cancel
按钮,它们的 IsDefault
和 IsCancel
属性分别设置为 True
。这两个按钮都有Click
关闭对话框的事件处理程序。
这里是相关的 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>
下面是代码:
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();
当我按下键盘上的Esc
按钮时(即使焦点不在Cancel
按钮上),对话框也会按预期关闭。但是,当我在焦点不在OK
按钮上时按Enter
键时,什么也没有发生。
我在对话框中有一个DataGrid
。当我选择数据网格中的任何行并按 Enter 时,我想关闭对话框。
如何做到这一点?
一些附加信息:我在对话框上有一个文本框。它具有Keyboard.PreviewKeyDown
事件的事件处理程序。当我在文本框中并按 Enter 键时,不应关闭对话框。 但我可以删除这个处理程序。重要的是解决上述问题。
private void tbxSearchString_PreviewKeyDown(object sender, KeyEventArgs e)
if (e.Key == Key.Enter)
this.Search(); // Does some searching
【问题讨论】:
你遇到的是默认和预期的行为,你不应该改变它。此外,您处理对话的方式有点异国情调。通常,您应该只在按钮的事件处理程序中将DialogResult
设置为true
或false
,并且应该在打开对话框的代码中完成逻辑,如下所示:if ((bool)diag.ShowDialog()) /*Here*/
。跨度>
+1 导致 H.B.太快了... :)
+1 指出正确的编码方式 (DialogResult
)! :)
【参考方案1】:
您的代码对我来说运行良好。当我按下回车键时它关闭对话框。你可以写 e.Handled = true;在 tbxSearchString_PreviewKeyDown 事件中搜索功能之后的行。所以它不会关闭对话框。
<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>
后面的代码
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;
【讨论】:
+1 表示e.Handled = true
。但是,当您设置 DisalogResult
属性时,this.Close()
不是必需的。
感谢 e.Handled = true - 在我的场景中,窗口用返回键关闭,事件冒泡到重新打开窗口的父窗口...;)【参考方案2】:
在 wpf 中没有内置的方法可以关闭对话框窗口。您需要做的是为您的默认按钮设置 DialogResult。所以你只需要以下内容:
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" />
代码隐藏:
private void btnOK_Click(object sender, RoutedEventArgs e)
DialogResult = true;
【讨论】:
问题不在于关闭(Close()
也实现了这一点,即使它不应该在对话框中使用),而是 DataGrid 上的焦点阻止了按钮被按下输入。【参考方案3】:
您不应该自己打电话给Close()
或处理PreviewKeyDown
。
正确的做法是使用确定/取消按钮,并使用Button.IsDefault
、Button.IsCancel
和Window.DialogResult
。如果在您的文本框中未处理“输入”按下,则按键将传播到Window
,并且将按下默认按钮。
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;
现在在表单中的 any 文本框上按 enter 或 escape 将关闭表单(显示正确的结果)
【讨论】:
当用户按 Enter 键时,TextBox 不会在默认模式下更新文本绑定。可以使用UpdateSourceTrigger=PropertyChanged
确保在 Enter-Key 处理之前更新绑定。【参考方案4】:
只需将 AcceptButton 成员设置为按钮属性名称即可。
AcceptButton = btnOK; // button used when ENTER is pressed
【讨论】:
AcceptButton 仅适用于 WinForms。以上是关于按下 Enter 键时如何关闭 WPF 窗口(对话框)?的主要内容,如果未能解决你的问题,请参考以下文章