2013-11-27 78 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

这应该是被接受的答案。简单,并且完全解决问题。 –