【问题标题】:Deselect selected item in wpf tree view (MVVM)取消选择 wpf 树视图(MVVM)中的选定项目
【发布时间】:2013-08-10 18:44:17
【问题描述】:

我正在使用 WPF 树视图,当我单击一个节点\项目后,它被选中。当用户第二次单击所选节点时,我希望取消选择此节点\项目,即我应该能够获得该事件。如果我单击已选择的选定节点\项目,则不会调用 IsSelected。如何让它工作?

<TreeView Grid.Column="0" Grid.Row="1" ItemsSource="{Binding source}" Name="mytreeview">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                <Setter Property="FontWeight" Value="Normal" />
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="FontWeight" Value="Bold" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding displaytext}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

在我的视图模型中我有

 public bool IsSelected
    {
        get 
        { 
            return _isSelected; 
        }
        set
        {
            if (value != _isSelected)
            {
                _isSelected = value;
                if (_isSelected)
                {
                  //my logic
                }

                this.OnPropertyChanged("IsSelected");
            }
        }
    }

【问题讨论】:

    标签: c# wpf mvvm treeview


    【解决方案1】:
    if (value != _isSelected)
    

    假设 UI 甚至试图设置一些东西,那条线会阻塞你的切换逻辑。像这样的东西至少应该修复那部分。

        set
        {
            if (value != _isSelected)
            {
                _isSelected = value;
                this.OnPropertyChanged("IsSelected");
            }
            else if(_isSelected)
            {
                IsSelected = false;
            }
        }
    

    否则 UI 会在设置值之前检查选择,您需要通过其他一些用户交互来处理它,例如处理单击时取消选择。

    【讨论】:

      【解决方案2】:

      IsSelected 属性仅在您选择新项目时更改。单击同一项目两次通常不会有任何效果。您需要在 TreeView 上注册 MouseDown 事件,然后在代码隐藏中强制取消选择该项目。

      【讨论】:

        【解决方案3】:

        我知道这有点晚了,但我最近有相同的要求(即在第二次单击时取消选择选定的 TreeViewItem),我通过在“样式”中为“MouseLeftButtonUp”事件声明一个事件处理程序来解决它TreeView 的 ItemContainerStyle 条目如下:

        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <EventSetter Event="MouseLeftButtonUp" Handler="TreeViewItem_MouseLeftButtonUp"/>
            </Style>
        </TreeView.ItemContainerStyle>
        

        后面代码中的事件处理程序如下:

        private TreeViewItem prevTVI;
        
        private void TreeViewItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem tvi = (TreeViewItem)sender;
            if (tvi == this.prevTVI)
            {
                this.prevTVI = null;
                if (tvi.IsSelected)
                    tvi.IsSelected = false;
            }
            else
                this.prevTVI = tvi;
            e.Handled = true;
        }
        

        现在,我想问一下是否有人认为这种方法破坏了 MVVM 模式?我个人不这么认为,因为事件处理程序只关心 View 及其对象而不是其他任何东西,但我想听听其他人怎么说,尤其是如果有人有替代方案的话。

        【讨论】:

        • 您是在写这个问题的答案还是提出一个新问题?请参阅how to answer 关于 SO 的问题。
        • @techspider 这是一个问题的答案,它适合我,但我更感兴趣的是看看其他人对 MVVM 设计模式的看法
        • 您可能必须将其作为一个新问题发布,将此问题作为参考。请参考this article on how to write a good answer on SO
        • @techspider 我认为不需要提出新问题。我真正想做的就是让其他人对我关于 MVVM 设计模式的解决方案发表意见(例如,是否有人认为它违反了任何 MVVM 规则)。应该没什么大不了的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-15
        • 2017-11-23
        • 1970-01-01
        • 2013-06-07
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        相关资源
        最近更新 更多