对于一个更简单的解决方案.覆盖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;
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,您可能不会喜欢这个答案...WPFTreeView是一个不友好的家伙。好吧,首先要做的事情是……
捕获更改所选项目的尝试:
最简单的方法是处理该SelectedItemChanged事件:
private void TreeView_SelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e)
{
e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果您使用 MVVM,那么您需要在Attached Property. 现在变得有点复杂了,如果您要创建一个Attached Property来处理SelectedItemChanged事件,那么您不妨实现一个SelectedItem Attached Property可以绑定到的Two-Way Mode。我不会在这里记录如何执行此操作,因为有很多相关的在线教程。
...并可能取消它:
如果您有SelectedItem Attached Property,那么您可以监视该属性何时发生变化。当然有一个问题……当视图模型发生变化时,UI 已经发生了变化。因此,虽然您可以阻止视图模型中的数据发生更改,但无法阻止 UI 中进行的选择。
但这并不是一个可怕的问题,因为使用 a Two-Way Binding,您将能够在必要时将 UI 选择设置回上一个项目...看一下这个伪代码:
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");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了满足您的要求,您还有很多工作要做……祝您好运。
| 归档时间: |
|
| 查看次数: |
4349 次 |
| 最近记录: |