Zac*_*son 8 .net wpf events messagebox
我一直在尝试让我的WPF应用程序提示用户丢弃未保存的更改,或者在使用TreeView导航时取消.
我想我发现了一个错误.MessageBox与PreviewMouseDown不兼容.它似乎"处理"了一个点击,无论如何显示一个MessageBox,它的e.Handled是如何设置的.
对于这个XAML ......
<TreeView Name="TreeViewThings"
...
PreviewMouseDown="TreeViewThings_PreviewMouseDown"
TreeViewItem.Expanded="TreeViewThings_Expanded"
TreeViewItem.Selected="TreeViewThings_Selected" >
Run Code Online (Sandbox Code Playgroud)
...比较这些替代方法......
Sub TreeViewNodes_PreviewMouseDown(...)
e.Handled = False
End Sub
Sub TreeViewNodes_PreviewMouseDown(...)
MessageBox.Show("Test", "Test", MessageBoxButton.OK)
e.Handled = False
End Sub
这两种方法表现不同.没有MessageBox,TreeViewNodes_Selected()或者TreeViewThings_Expanded()会执行.使用MessageBox,他们不会.
这是一个错误还是在这里发生了一些我应该理解的事情?
我遇到了完全相同的问题,你认为 MessageBox 把事情搞砸了,这是正确的。老实说,在切换到 WPF 之前,我在使用 Windows 窗体时还遇到了 MessageBox 的其他问题。也许这只是一些百年历史的错误变成了一项功能(就像微软经常发生的那样)?
无论如何,我能为您提供的唯一解决方案就是对我有用的解决方案。我在使用列表框时遇到类似的情况 - 如果表单中的数据发生更改,当列表框的选择发生变化时(通过单击新项目或使用“向上”或“向下”键),我在消息框中为用户提供了是否保存、丢弃或取消的选择。
当然,使用处理 ListBox 的 MouseDown 或 PreviewMouseDown 事件的直接方法对于 MessageBox 来说效果不佳。这是有效的。
我有一个数据模板来显示列表框中的项目(我几乎希望您也有相同的):
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=NAME}" KeyDown="checkForChanges" MouseDown="checkForChanges"/>
</DataTemplate>
</ListBox.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)
请注意我如何将 KeyDown 和 MouseDown 事件处理程序移至 TextBlock 控件。我保留了相同的代码隐藏:
// The KeyDown handler
private void checkForChanges(object sender, KeyEventArgs e) {
e.Handled = checkForChanges();
}
// Method that checks if there are changes to be saved or discard or cancel
private bool checkForChanges() {
if (Data.HasChanges()) {
MessageBoxResult answer = MessageBox.Show("There are unsaved changes. Would you like to save changes now?", "WARNING", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
if (answer == MessageBoxResult.Yes) {
Data.AcceptDataChanges();
} else if (answer == MessageBoxResult.Cancel) {
return true;
}
return false;
}
return false;
}
// The MouseDown handler
private void checkForChanges(object sender, MouseButtonEventArgs e) {
e.Handled = checkForChanges();
}
Run Code Online (Sandbox Code Playgroud)
附带说明一下,当 ListBox 中的 ItemsSource 绑定到 DataTable 中的所选项目发生更改(我不知道您是否使用 DataTables/Sets)时,Binding 总是将我的 DataRows 标记为“已修改”,这很奇怪。为了解决这个问题,一旦选择已经更改,我就会丢弃所有未处理的更改(因为我处理了在此之前发生的 MouseDown 事件中所需的任何内容):
<ListBox IsSynchronizedWithCurrentItem="True" [...] SelectionChanged="clearChanges"> ... </ListBox>
Run Code Online (Sandbox Code Playgroud)
以及处理程序的隐藏代码:
private void clearChanges(object sender, SelectionChangedEventArgs e) {
Data.cancelChanges();
}
Run Code Online (Sandbox Code Playgroud)