禁用 WPF TreeView(或 TreeViewItem)选择?

发布于 2024-10-09 17:39:17 字数 426 浏览 0 评论 0原文

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

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

Is there a nice way (except retemplating the whole TreeViewItem.Template) to disable selection in TreeView?

I am basically looking for the ItemsControl style of the TreeView (An ItemsControl is the best use to 'disable' selection on ListBox, read this post)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

迷迭香的记忆 2024-10-16 17:39:17

试试这个:

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

Try this:

<Trigger Property="HasItems" Value="true">
   <Setter Property="Focusable" Value="false" />
</Trigger>
万人眼中万个我 2024-10-16 17:39:17

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

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

This did the trick for me (based on this answer, but no tied to item - selection is disabled whatsoever):

<TreeView>
  <TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
      <Setter Property="Focusable" Value="False" />
    </Style>
  </TreeView.ItemContainerStyle>
</TreeView>
苦妄 2024-10-16 17:39:17

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

<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();
    }
}

现在您不必去打猎了!

Based off of the links to the currently accepted answer, I implemented this in my project:

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

Works for TreeViewItem as well. And in the view model:

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

Now you don't have to go hunting!

長街聽風 2024-10-16 17:39:17

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

Whenever an item is selected, you could "unselect" it. Ex. modify the code from http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx or use a MVVM approach (see http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx) and always set IsSelected back to false.

纵情客 2024-10-16 17:39:17

我决定编写一个可重用的行为,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> 

I decided to write a reusable behavior, 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

Usage:

<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> 
金橙橙 2024-10-16 17:39:17

我尝试过这个,它对我有用。因为我有一个简单且非动态的树视图。但我认为通过将其放在某种风格中可以发挥作用

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

I tried this and it worked for me. Because I have a simple and not dynamic treeview. But I think it can work by putting it in a style

<TreeViewItem ... Focusable="False" IsSelected="False"/>
红墙和绿瓦 2024-10-16 17:39:17

我只是在选择 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;
}

I just unselected the TreeViewItems as they get selected.
I use TreeView only once. However if I added it in several places I would consider looking in to adding this to a Attached Behavior.

Xaml:

<TreeView SelectedItemChanged="TreeView_SelectionChanged">

Code behind:

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;
}
赴月观长安 2024-10-16 17:39:17

我的做法与接受的答案不同:

假设您的 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;
    }

}

I did this a differently than the accepted answer:

Lets say that you have a property in your ViewModel (say 'ShouldPreventSelection')
Now when ShouldPreventSelection is true you want selection to be disabled:

In your TreeView fire the PreviewSelected event like so:

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

Then in the codebehind you can the following:

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文