WPF:TreeViewのExpanderをStyleの変更をせずに非表示にする
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <TreeView> <TreeView.Resources> <Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}"> <Setter Property="IsExpanded" Value="True" /> <Setter Property="local:Att.IsHideExpander" Value="True" /> </Style> </TreeView.Resources> <TreeViewItem Header="parent"> <TreeViewItem Header="child" /> </TreeViewItem> <TreeViewItem Header="parent"> <TreeViewItem Header="child" /> </TreeViewItem> <TreeViewItem Header="parent"> <TreeViewItem Header="child"> <TreeViewItem Header="child"/> </TreeViewItem> </TreeViewItem> </TreeView> </Grid> </Window>
上記のような画面で、ツリービューのエクスパンダーを非表示にしようと考えました。
ネットでは良くItemContainerStyleを変更する方法を見かけるのですが、 今回は他のStyleとの兼ね合いがあり、ItemContainerStyleを変更しない対応が必要でした。 そこで添付プロパティを使ってみたところ、うまくいきましたのでメモしておきます。
追加した添付プロパティ(とりあえずWpfApplication名前空間に作成)
public class Att { public static bool GetIsHideExpander(DependencyObject obj) { return (bool)obj.GetValue(IsHideExpanderProperty); } public static void SetIsHideExpander(DependencyObject obj, bool value) { obj.SetValue(IsHideExpanderProperty, value); } // Using a DependencyProperty as the backing store for IsHideExpander. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsHideExpanderProperty = DependencyProperty.RegisterAttached("IsHideExpander", typeof(bool), typeof(Att), new PropertyMetadata(false, IsHideExpander_PropertyChanged)); private static void IsHideExpander_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { TreeViewItem treeViewItem = d as TreeViewItem; if (treeViewItem == null) return; treeViewItem.Loaded += TreeViewItem_Loaded; } private static void TreeViewItem_Loaded(object sender, RoutedEventArgs e) { TreeViewItem treeViewItem = sender as TreeViewItem; if (treeViewItem == null) return; treeViewItem.Loaded -= TreeViewItem_Loaded; ToggleButton tg = FindChild<ToggleButton>(treeViewItem); if (tg != null) { tg.Visibility = Visibility.Hidden; } } public static T FindChild<T>(DependencyObject parent) where T : DependencyObject { if (parent == null) return null; if (parent is T) return parent as T; T child = null; int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { var c = VisualTreeHelper.GetChild(parent, i); child = FindChild<T>(c); if (child != null) break; } return child; } }
xamlはTreeView.Resourcesタグを修正
<TreeView.Resources> <Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}"> <Setter Property="IsExpanded" Value="True" /> <Setter Property="local:Att.IsHideExpander" Value="True" /> </Style> </TreeView.Resources>
上記コードを追加することで、エクスパンダーが非表示となります。