Отключить WPF TreeView (или TreeViewItem) выбор? - PullRequest
4 голосов
/ 29 декабря 2010

Есть ли хороший способ (кроме повторного сшивания TreeViewItem.Template) отключить выбор в TreeView?

Я в основном ищу стиль ItemsControl для TreeView (ItemsControl - лучший способ отключить выбор на ListBox, читать эту запись)

Ответы [ 7 ]

17 голосов
/ 27 ноября 2013

Попробуйте это:

<Trigger Property="HasItems" Value="true">
   <Setter Property="Focusable" Value="false" />
</Trigger>
3 голосов
/ 26 июля 2013

Исходя из ссылок на принятый в настоящее время ответ, я реализовал это в своем проекте:

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

Теперь вам не нужно охотиться!

2 голосов
/ 05 марта 2018

Это помогло мне (основываясь на этом ответе, но без привязки к элементу - выбор вообще отключен):

<TreeView>
  <TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
      <Setter Property="Focusable" Value="False" />
    </Style>
  </TreeView.ItemContainerStyle>
</TreeView>
1 голос
/ 21 сентября 2016

Я просто отменил выбор TreeViewItems по мере их выбора. Я использую TreeView только один раз. Однако, если бы я добавил несколько размещенных мест, я бы подумал о том, чтобы добавить это к атакованному поведению.

Xaml:

<TreeView SelectedItemChanged="TreeView_SelectionChanged">

Код:

private void TreeView_SelectionChanged(object sender, RoutedEventArgs e)
{
    var myTreeView = sender as TreeView;
    if (myTreeView == null) return;
    var selectedItem = (TreeViewItem)myTreeView.SelectedItem;
    if (selectedItem ==null) return;
    selectedItem.IsSelected = false;
}
1 голос
/ 29 декабря 2010

Я решил написать многоразовое поведение, 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> 
0 голосов
/ 01 февраля 2012

Я сделал это не так, как принятый ответ:

Допустим, у вас есть свойство в вашей 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;
    }

}
0 голосов
/ 29 декабря 2010

Каждый раз, когда элемент выбран, вы можете «отменить выбор» его.Ex.измените код с http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx или используйте подход MVVM (см. http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx) и всегда устанавливайте IsSelected обратно в false.

...