2013-11-27 77 views
4

有沒有辦法捕獲嘗試更改WPF的TreeView中當前選定的項目並可能取消它?WPF,Treeview選擇更改

樹視圖中的元素表示具有某些屬性的頁面。我想問問用戶他是否想放棄對頁面所做的更改,保存或保留在當前頁面中。

+0

是否有任何可能通過處理PreviewMouseDown(e.Handled = true)來實現此目的。 – Ravuthasamy

回答

2

那麼你可能不會喜歡這個答案...... WPF TreeView是一個不友好的傢伙。好吧,首要的事情...

捕捉試圖改變所選項目

做到這一點,最簡單的方法是處理SelectedItemChanged事件:

private void TreeView_SelectedItemChanged(object sender, 
RoutedPropertyChangedEventArgs<object> e) 
{ 
    e.Handled = true; 
} 

不幸的是,如果你使用MVVM,那麼你需要在Attached Property內處理這個。現在變得更復雜了,如果你打算創建一個Attached Property來處理SelectedItemChanged事件,那麼你也可以實現SelectedItemAttached Property,你可以綁定到Two-Way Mode。我不會在這裏記錄如何做到這一點,因爲這裏有很多在線教程。

...並可以取消其

如果你有SelectedItemAttached Property,那麼你就可以監控時屬性更改。當然有一個問題......當改變進入你的視圖模型時,UI已經改變了。因此,儘管您可以阻止視圖模型中的數據發生更改,但無法停止在UI中進行選擇。

這不是一個可怕的問題,但因爲有Two-Way Binding,您將能夠在必要時設置的用戶界面選擇回到上一個項目......看看這個僞代碼:

public YourDataType SelectedItem 
{ 
    get { return selectedItem; } 
    set 
    { 
     if (selectedItem != value) 
     { 
      if (selectedItem.HasChanges) 
      { 
       if (WindowManager.UserAcceptsLoss()) 
       { 
        selectedItem = value; 
        NotifyPropertyChanged("SelectedItem"); 
       } 
       else ResetSelectedItem(selectedItem); 
      } 
      else 
      { 
       selectedItem = value; 
       NotifyPropertyChanged("SelectedItem"); 
      } 
     } 
    } 
} 

爲了滿足您的要求,您需要做很多工作,祝您好運。

+0

你說得對,我不喜歡這個答案:( – Spook

7

更簡單的解決方案。覆蓋PreviewMouseDown,你會得到想要的結果。

private void Tree_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     // first did the user click on a tree node? 
     var source = e.OriginalSource as DependencyObject; 
     while (source != null && !(source is TreeViewItem)) 
      source = VisualTreeHelper.GetParent(source); 
     source = source as TreeViewItem; 
     if (source == null) return; 

     var treeView = sender as TreeView; 
     if (treeView == null) return; 

     // validate our current item to decide if we allow the change 
     // or do whatever checks you wish 
     if (!ItemIsValid(treeView.SelectedItem)) 
     { 
      // it's not valid, so cancel the attempt to select an item. 
      e.Handled = true; 
     } 

     // Maybe you want to check the about to be selected value? 
     MyClass data = source.DataContext; 
     if (!CanSelect(data)) 
     { 
      // we can't select this, so cancel the attempt to select. 
      e.Handled = true; 
     } 
    } 
+0

這應該是被接受的答案。簡單,並且完全解決問題。 –