有没有办法捕获尝试更改WPF的TreeView中当前选定的项目并可能取消它?WPF,Treeview选择更改
树视图中的元素表示具有某些属性的页面。我想问问用户他是否想放弃对页面所做的更改,保存或保留在当前页面中。
有没有办法捕获尝试更改WPF的TreeView中当前选定的项目并可能取消它?WPF,Treeview选择更改
树视图中的元素表示具有某些属性的页面。我想问问用户他是否想放弃对页面所做的更改,保存或保留在当前页面中。
那么你可能不会喜欢这个答案...... WPF TreeView
是一个不友好的家伙。好吧,首要的事情...
捕捉试图改变所选项目:
做到这一点,最简单的方法是处理SelectedItemChanged
事件:
private void TreeView_SelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e)
{
e.Handled = true;
}
不幸的是,如果你使用MVVM,那么你需要在Attached Property
内处理这个。现在变得更复杂了,如果你打算创建一个Attached Property
来处理SelectedItemChanged
事件,那么你也可以实现SelectedItem
Attached Property
,你可以绑定到Two-Way Mode
。我不会在这里记录如何做到这一点,因为这里有很多在线教程。
...并可以取消其:
如果你有SelectedItem
Attached 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");
}
}
}
}
为了满足您的要求,您需要做很多工作,祝您好运。
你说得对,我不喜欢这个答案:( – Spook
更简单的解决方案。覆盖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;
}
}
这应该是被接受的答案。简单,并且完全解决问题。 –
是否有任何可能通过处理PreviewMouseDown(e.Handled = true)来实现此目的。 – Ravuthasamy