【问题标题】:Disable WPF TreeView (or TreeViewItem) selection?禁用 WPF TreeView(或 TreeViewItem)选择?
【发布时间】:2021-01-11 21:31:38
【问题描述】:

有没有很好的方法(除了重新模板化整个TreeViewItem.Template)来禁用TreeView 中的选择?

我基本上在寻找TreeViewItemsControl 样式(ItemsControl 是在ListBox 上“禁用”选择的最佳用途,请阅读this 帖子)

【问题讨论】:

标签: wpf xaml treeview selection itemscontrol


【解决方案1】:

试试这个:

<Trigger Property="HasItems" Value="true">
   <Setter Property="Focusable" Value="false" />
</Trigger>

【讨论】:

  • 为了扩展这个答案,在叶子 TreeViewItems 上将 Focusable 设置为 false 似乎也可以防止它们被选中。
  • 它还可以防止选择没有子节点的节点,考虑一下。
  • 不幸的是,当折叠节点时,这仍然会导致根被选中
【解决方案2】:

这对我有用(基于this 答案,但与项目无关 - 选择被禁用):

<TreeView>
  <TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
      <Setter Property="Focusable" Value="False" />
    </Style>
  </TreeView.ItemContainerStyle>
</TreeView>

【讨论】:

    【解决方案3】:

    根据当前接受的答案的链接,我在我的项目中实现了这一点:

    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </ListView.ItemContainerStyle>
    

    也适用于 TreeViewItem。在视图模型中:

    protected bool _DisableSelection;
    private bool _IsSelected;
    public bool IsSelected
    {
        get { return _IsSelected; }
        set
        {
            if (value == _IsSelected) return;
            _IsSelected = _DisableSelection ? false : value;
            NotifyPropertyChanged();
        }
    }
    

    现在你不必去打猎了!

    【讨论】:

      【解决方案4】:

      无论何时选择一个项目,您都可以“取消选择”它。前任。从 http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx 修改代码或使用 MVVM 方法(请参阅 http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx)并始终将 IsSelected 设置回 false。

      【讨论】:

      • 虽然理论上可以回答这个问题,但我们希望您在回答中包含链接文章的基本部分,并提供link for reference。不这样做会使答案面临链接失效的风险。
      【解决方案5】:

      我决定写一个可重用的行为,HTH:

      Namespace Components
        Public NotInheritable Class TreeViewBehavior
      
          Public Shared Function GetIsTransparent(
            ByVal element As TreeViewItem) As Boolean
            If element Is Nothing Then Throw New ArgumentNullException("element")
            Return element.GetValue(IsTransparentProperty)
          End Function
          Public Shared Sub SetIsTransparent(ByVal element As TreeViewItem,
                                             ByVal value As Boolean)
            If element Is Nothing Then Throw New ArgumentNullException("element")
            element.SetValue(IsTransparentProperty, value)
          End Sub
          Public Shared ReadOnly IsTransparentProperty As DependencyProperty =
            DependencyProperty.RegisterAttached("IsTransparent", GetType(Boolean),
              GetType(TreeViewBehavior),
              New FrameworkPropertyMetadata(False,
                AddressOf IsTransparent_PropertyChanged))
          Private Shared Sub IsTransparent_PropertyChanged(
            ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
            Dim tvi = DirectCast(sender, TreeViewItem)
            Dim isTransparent = CBool(e.NewValue)
      
            If isTransparent Then
              AddHandler tvi.Selected, AddressOf tvi_Selected
            Else
              RemoveHandler tvi.Selected, AddressOf tvi_Selected
            End If
          End Sub
          Private Shared Sub tvi_Selected(ByVal sender As Object,
                                          ByVal e As RoutedEventArgs)
            Dim treeViewItem = DirectCast(sender, TreeViewItem)
            If Not treeViewItem.IsSelected Then Exit Sub
      
            treeViewItem.Dispatcher.Invoke(
              Sub(tvi As TreeViewItem) tvi.IsSelected = False,
              System.Windows.Threading.DispatcherPriority.Send,
              treeViewItem)
          End Sub
      
        End Class
      End Namespace
      

      用法:

      <Window xmlns:components="clr-namespace:WpfApplication.Components">
        <TreeView>
          <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
              <Setter 
                Property="components:TreeViewBehavior.IsTransparent" 
                Value="True" />
            </Style>
          </TreeView.ItemContainerStyle>
        </TreeView>
      </Window> 
      

      【讨论】:

        【解决方案6】:

        我试过这个,它对我有用。因为我有一个简单而不是动态的树视图。但我认为它可以通过把它放在一个样式中来工作

        <TreeViewItem ... Focusable="False" IsSelected="False"/>
        

        【讨论】:

        • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        • 感谢@NeoAnderson。我是新来的,但我只是想帮忙。
        • 我们都想帮忙。我们的目标是尽可能高效地做到这一点。感谢您解释代码 sn-p。
        【解决方案7】:

        我只是在 TreeViewItems 被选中时取消选择它们。 我只使用一次 TreeView。但是,如果我在几个地方添加它,我会考虑将其添加到附加行为中。

        Xaml:

        <TreeView SelectedItemChanged="TreeView_SelectionChanged">
        

        后面的代码:

        private void TreeView_SelectionChanged(object sender, RoutedEventArgs e)
        {
            if (!(sender is TreeView myTreeView)) return;
            var selectedItem = (TreeViewItem)myTreeView.SelectedItem;
            if (selectedItem == null) return;
            selectedItem.IsSelected = false;
        }
        

        【讨论】:

          【解决方案8】:

          我这样做与接受的答案不同:

          假设您的 ViewModel 中有一个属性(例如“ShouldPreventSelection”) 现在,当 ShouldPreventSelection 为 true 时,您希望禁用选择:

          在您的 TreeView 中触发 PreviewSelected 事件,如下所示:

          <TreeView Name="TreeView1"
               ...
               PreviewSelected="TreeView1_PreviewSelected"
               ..
          />
          

          然后在代码隐藏中您可以执行以下操作:

          private void TreeView1_PreviewSelected(object sender, RoutedEventArgs e)
          {
              MyViewModel myViewModel = TreeView1.DataContext as MyViewModel;
              if (myViewModel == null)
              {
                  return;
              }
              if (myViewModel .ShouldPreventSelection)
              {
                  e.Handled = true;
              }
          
          }
          

          【讨论】:

          • WPF TreeView 上似乎没有任何 PreviewSelected 事件。
          • 嗯,我使用的是 Telerik 的 RadTreeView,我猜我认为 PreviewSelected 事件在常规 TreeView 中可用。
          猜你喜欢
          • 2011-08-23
          • 1970-01-01
          • 1970-01-01
          • 2011-07-20
          • 1970-01-01
          • 2014-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多