WPF:MessageBox是否破解PreviewMouseDown? [英] WPF: Does MessageBox Break PreviewMouseDown?

查看:83
本文介绍了WPF:MessageBox是否破解PreviewMouseDown?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图让我的WPF应用程序提示用户丢弃未保存的更改,或者在使用TreeView导航时取消。

I've been trying to get my WPF application to prompt users to either discard their unsaved changes or to cancel when they navigate using a TreeView.

我想我发现了一个错误。 MessageBox与PreviewMouseDown不兼容。它似乎是处理一个点击,无论它的e.Handled如何设置,如果有一个MessageBox显示。

I think I've found a bug. The MessageBox does not play nice with PreviewMouseDown. It seems to "handle" a click regardless of how its e.Handled is set if there's a MessageBox shown.

对于这个XAML ...

For this XAML...

<TreeView Name="TreeViewThings"
    ...
    PreviewMouseDown="TreeViewThings_PreviewMouseDown"
    TreeViewItem.Expanded="TreeViewThings_Expanded"
    TreeViewItem.Selected="TreeViewThings_Selected" >

...比较这些替代方法...

...compare these alternative methods...


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,他们不会。

These two methods behave differently. Without the MessageBox, TreeViewNodes_Selected() or TreeViewThings_Expanded() will execute. With the MessageBox, they won't.

这是一个错误,还是有什么事情在这里,我应该明白?

Is this a bug or is there something going on here that I should understand?

推荐答案

我正在遇到同样的问题,您正确地认为MessageBox正在扭转问题。说实话,在切换到WPF之前,在使用Windows窗体时,我遇到了MessageBox的其他问题。也许这只是一个百年老的bug成为一个功能(通常是与微软一样)?

I'm having precisely the same problem and you're right in thinking that MessageBox is screwing things up. To be honest, I've had other issues with MessageBox while working with Windows Forms before switching to WPF. Maybe it's just some century-old bug that became a feature (as often it is with Microsoft)?

无论如何,唯一可以提供给您的解决方案是这对我有用我遇到一个类似的情况下使用ListBox的问题 - 如果表单中的数据有更改,当选择列表框更改(通过点击新项目或使用键上或下),我在MessageBox中为用户提供了选择是否保存,丢弃或取消。

In any case, the only solution I can offer you is the one that has worked for me. I was having problems with getting a similar situation to work with a ListBox - if there were changes to data in the form, when selection of the ListBox changed (either by clicking on new item or using keys "Up" or "Down"), I offered user a choice in the MessageBox whether to save, discard or cancel.

自然地使用直接处理ListBox的MouseDown或PreviewMouseDown事件的方法对于消息框。这是有效的。

Naturally using the direct approach of handling ListBox's MouseDown or PreviewMouseDown events didn't work well with a MessageBox. Here's what worked.

我有一个数据模板来显示我的ListBox中的项目(我几乎期望你有相同的):

I have a data template to display items in my ListBox (I'm almost expecting you to have the same):

<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Path=NAME}" KeyDown="checkForChanges" MouseDown="checkForChanges"/>
    </DataTemplate>
</ListBox.ItemTemplate>

强>而不是。我保持相同的代码隐藏:

Note how I've moved the KeyDown and MouseDown event handlers to the TextBlock control instead. I kept the same code-behind:

// 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();
}

作为附注,Binding总是将DataRows标记为已修改ListBox中已选择的项目已将ItemsSource绑定到一个DataTable,它会改变(我不知道你是否使用DataTables / Sets)。为了争取这一点,一旦选择已经被更改,我就丢弃任何未处理的更改(因为我在处理之前发生的MouseDown事件处理任何事情):

As a side note, it's odd how Binding always marks my DataRows as Modified when the selected item in the ListBox, which has ItemsSource bound to a DataTable, changes (I don't know if you're using DataTables/Sets). To battle that, I discard any unhandled changes once the selection has already been changed (because I handle anything that's necessary in the event MouseDown that occurs prior to that):

<ListBox IsSynchronizedWithCurrentItem="True" [...] SelectionChanged="clearChanges"> ... </ListBox>

处理程序的代码隐藏:

private void clearChanges(object sender, SelectionChangedEventArgs e) {
    Data.cancelChanges();
}

这篇关于WPF:MessageBox是否破解PreviewMouseDown?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆