WPF,Treeview选择更改

Spo*_*ook 6 c# wpf treeview selection

有没有办法捕获尝试更改WPF的TreeView中当前选定的项目并可能取消它?

树视图中的元素表示具有某些属性的页面.我想询问用户是否要放弃在页面上进行的更改,保存或保留在当前页面中.

JB.*_*JB. 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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果您想使用鼠标以外的其他东西进行选择,则此操作将无效。 (3认同)

She*_*dan 4

好吧,您可能不会喜欢这个答案...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)

为了满足您的要求,您还有很多工作要做……祝您好运。