在wpf树视图(MVVM)中取消选择所选项

时间:2013-08-08 21:26:10

标签: c# wpf mvvm treeview

我正在使用WPF树视图,一旦它被选中,我点击一个节点\ item。当用户第二次点击所选节点时,我希望取消选择此节点\ item,即我应该能够获得该事件。如果我单击已选择的所选节点\项目,则不会调用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");
            }
        }
    }

3 个答案:

答案 0 :(得分:0)

if (value != _isSelected)

假设用户界面甚至试图设置某些内容,那么这一行就会阻止你的切换逻辑。这样的事情至少应该解决这个问题。

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

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

答案 1 :(得分:0)

我知道这有点晚了但我最近有同样的要求(即在第二次点击时取消选择一个选定的TreeViewItem)并通过在'Style'中声明'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及其对象而不是其他任何东西,但我想听听其他人说的话,特别是如果有人有其他选择。

答案 2 :(得分:-1)

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