2009-02-13 35 views
8

我一直在试图让我的WPF应用程序提示用户放弃他们未保存的更改,或者在他们使用TreeView进行导航时取消。WPF:是否MessageBox Break PreviewMouseDown?

我想我已经找到了一个错误。 MessageBox对于PreviewMouseDown不会很好。无论如何设置e.Handled,如果显示MessageBox,它似乎都“处理”了一次点击。

对于这个XAML ...

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

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

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

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

回答

2

我有完全相同的问题,你认为MessageBox是搞砸了。说实话,在切换到WPF之前,在使用Windows窗体时,我遇到了MessageBox的其他问题。也许这只是一个有百年历史的bug,成为一个功能(与微软一样)?

无论如何,我能为您提供的唯一解决方案就是为我工作的解决方案。我遇到了与使用ListBox类似的情况的问题 - 如果表单中的数据发生更改,当ListBox的选择发生更改(通过单击新项目或使用键“Up”或“Down”)时,我在MessageBox中为用户提供了一个选择,保存,放弃还是取消。

当然,使用处理ListBox的MouseDown或PreviewMouseDown事件的直接方法并不适用于MessageBox。这是有用的。

我有一个数据模板来显示在列表框中我的项目(我几乎希望你有相同):

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

注意我是如何移动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(); 
} 

作为一个侧面说明,这是奇怪的是如何绑定时ListBox中选定的项目,它具有的ItemsSource绑定到数据表,修改(我不为改良总是标志着我的DataRows不知道你是否使用DataTables/Sets)。战斗,我放弃所有未处理的变化,一旦选择已经改变(因为我处理任何事情那是在此之前发生的事件MouseDown必要):

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

和代码隐藏的处理程序:

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

这就是我得到的。它可以工作,但不太理想......

Sub TreeViewNodes_PreviewMouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) 
    If UnsavedChangesExist() Then 
     MessageBox.Show("You have unsaved changes.", "Unsaved Changes", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK) 
     e.Handled = True 
    End If 
End Sub 

这需要用户点击“确定”后,手动点击“放弃更改”按钮(靠近“保存”按钮),通过点击另一个“你确定吗?”消息框,然后再次使用树导航。

相关问题