【发布时间】:2021-01-11 21:31:38
【问题描述】:
有没有很好的方法(除了重新模板化整个TreeViewItem.Template)来禁用TreeView 中的选择?
我基本上在寻找TreeView 的ItemsControl 样式(ItemsControl 是在ListBox 上“禁用”选择的最佳用途,请阅读this 帖子)
【问题讨论】:
标签: wpf xaml treeview selection itemscontrol
有没有很好的方法(除了重新模板化整个TreeViewItem.Template)来禁用TreeView 中的选择?
我基本上在寻找TreeView 的ItemsControl 样式(ItemsControl 是在ListBox 上“禁用”选择的最佳用途,请阅读this 帖子)
【问题讨论】:
标签: wpf xaml treeview selection itemscontrol
试试这个:
<Trigger Property="HasItems" Value="true">
<Setter Property="Focusable" Value="false" />
</Trigger>
【讨论】:
这对我有用(基于this 答案,但与项目无关 - 选择被禁用):
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Focusable" Value="False" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
【讨论】:
根据当前接受的答案的链接,我在我的项目中实现了这一点:
<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();
}
}
现在你不必去打猎了!
【讨论】:
无论何时选择一个项目,您都可以“取消选择”它。前任。从 http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx 修改代码或使用 MVVM 方法(请参阅 http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx)并始终将 IsSelected 设置回 false。
【讨论】:
我决定写一个可重用的行为,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>
【讨论】:
我试过这个,它对我有用。因为我有一个简单而不是动态的树视图。但我认为它可以通过把它放在一个样式中来工作
<TreeViewItem ... Focusable="False" IsSelected="False"/>
【讨论】:
我只是在 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;
}
【讨论】:
我这样做与接受的答案不同:
假设您的 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;
}
}
【讨论】:
TreeView 上似乎没有任何 PreviewSelected 事件。