2009-02-13 40 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 

這需要用戶點擊「確定」後,手動點擊「放棄更改」按鈕(靠近「保存」按鈕),通過點擊另一個「你確定嗎?」消息框,然後再次使用樹導航。

相關問題