none
TreeViewにて選択した際の背景色を変更したい RRS feed

  • 質問

  • ご存じの方がいれば教えていただきたいです。

    TreeViewにて選択した際の背景色を変更したいです。

    上記で青く選択される色を薄く変更したいです。

    TreeViewに選択色を指定するプロパティはなく、

    TreeViewにテンプレートを指定する必要があるのではないかと思っております。

    下記のMicrosoftのURLにテンプレートの例はあったのですが、

    値は単に例としてくださいとの記載がありました。

    http://msdn.microsoft.com/ja-jp/library/ms788727(VS.80).aspx

    標準の機能から背景色を変更したいだけなのですが、

    このような場合には、どのようにしてコントロールテンプレートを作成すればよいのでしょうか。

    以下のような流れだと思っているのですが・・・

    1.標準のTreeViewのコントロールテンプレートを何らかの方法で抽出する。

    2.選択色を定義している部分を変更したい色に変更

    3.TreeView内で、1で作成したテンプレートをバインドする。

    <XAML>

        <Grid Margin="10">
    
            <Border BorderBrush="Black" BorderThickness="1">
                <Grid>
                    <TreeView ItemsSource="{Binding Items}" BorderThickness="0 1 0 0">
                        <TreeView.ItemTemplate>
                            <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition SharedSizeGroup="A"/>
                                        <ColumnDefinition SharedSizeGroup="T"/>
                                        <ColumnDefinition SharedSizeGroup="B"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0" Text="{Binding A}" />      
                                    <TextBlock Grid.Column="4" Text="{Binding B}" />
                                </Grid>
    
                                <HierarchicalDataTemplate.ItemTemplate>
                                    <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition/>
                                                <ColumnDefinition/>
                                                <ColumnDefinition/>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Grid.Column="0" Text="{Binding A}"/>
                                            <TextBlock Grid.Column="4" Text="{Binding B}"/>
                                        </Grid>
                                    </HierarchicalDataTemplate>
                                </HierarchicalDataTemplate.ItemTemplate>
                            </HierarchicalDataTemplate>
                        </TreeView.ItemTemplate>
                    </TreeView>
                </Grid>
            </Border>
        </Grid>

    コードビハインド

        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
    
                DataContext = new Item
                {
                    Items = new Item[]
                    {
                        new Item
                        {
                            A = "TESTTE",
                            B = "TESETES",
                            Items = new Item[]
                            {
                                new Item { A = "TEST1",  B = "AAA" },
                                new Item { A = "TEST2",  B = "BBB" },
                                new Item { A = "TEST3", B = "CCC" },
                            },
                        },
    
                    },
                };
            }
        }
    
        public class Item
        {
            public string A { get; set; }
            public string B { get; set; }
            public Item[] Items { get; set; }
            public Item()
            {
                Items = new Item[0];
            }
        }


    • 編集済み sasagaki 2013年11月22日 11:11
    2013年11月22日 10:28

回答

  • こんな

    <TreeView ItemsSource="{Binding Items}" BorderThickness="0 1 0 0">
        <TreeView.Resources>
            <SolidColorBrush Color="LightPink" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
            <SolidColorBrush Color="Red" x:Key="{x:Static SystemColors.HighlightTextBrushKey}"/>
        </TreeView.Resources>
                        
        <!-- 省略 -->
    </TreeView>

    リンク先(あるいは4.0以降が載ってるリンクでその他のバージョン)でTreeViewItemのテンプレートには以下のような記載があります。

    <Trigger Property="IsSelected"
            Value="true">
        <Setter TargetName="Bd"
            Property="Background"
            Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
    </Trigger>
    

    これは選択されたらBackgroundがSystemColors.HilightBrushKeyになるトリガーです。
    ですから、このキーが参照するBrushを変更してやると、テンプレートの変更なしで色を変更できます。

    とりあえず実行中のコントロールのテンプレートがどのようなものかは、こんな感じで調べられます。

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var style = (Style)FindResource(typeof(TreeViewItem));
        foreach (Setter setter in style.Setters)
        {
            if (setter.Property == Control.TemplateProperty)
            {
                ControlTemplate temp = (ControlTemplate)setter.Value;
                System.Diagnostics.Debug.WriteLine(GetTemplateText(temp));
            }
        }
    }
    
    static string GetTemplateText(ControlTemplate temp)
    {
        StringBuilder sb = new StringBuilder();
        System.Xml.XmlWriter xmlwrite = System.Xml.XmlWriter.Create(sb, new System.Xml.XmlWriterSettings() { Indent = true });
        System.Windows.Markup.XamlWriter.Save(temp, xmlwrite);
        return sb.ToString();
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク sasagaki 2013年11月24日 23:09
    2013年11月22日 13:06

すべての返信

  • こんな

    <TreeView ItemsSource="{Binding Items}" BorderThickness="0 1 0 0">
        <TreeView.Resources>
            <SolidColorBrush Color="LightPink" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
            <SolidColorBrush Color="Red" x:Key="{x:Static SystemColors.HighlightTextBrushKey}"/>
        </TreeView.Resources>
                        
        <!-- 省略 -->
    </TreeView>

    リンク先(あるいは4.0以降が載ってるリンクでその他のバージョン)でTreeViewItemのテンプレートには以下のような記載があります。

    <Trigger Property="IsSelected"
            Value="true">
        <Setter TargetName="Bd"
            Property="Background"
            Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
    </Trigger>
    

    これは選択されたらBackgroundがSystemColors.HilightBrushKeyになるトリガーです。
    ですから、このキーが参照するBrushを変更してやると、テンプレートの変更なしで色を変更できます。

    とりあえず実行中のコントロールのテンプレートがどのようなものかは、こんな感じで調べられます。

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var style = (Style)FindResource(typeof(TreeViewItem));
        foreach (Setter setter in style.Setters)
        {
            if (setter.Property == Control.TemplateProperty)
            {
                ControlTemplate temp = (ControlTemplate)setter.Value;
                System.Diagnostics.Debug.WriteLine(GetTemplateText(temp));
            }
        }
    }
    
    static string GetTemplateText(ControlTemplate temp)
    {
        StringBuilder sb = new StringBuilder();
        System.Xml.XmlWriter xmlwrite = System.Xml.XmlWriter.Create(sb, new System.Xml.XmlWriterSettings() { Indent = true });
        System.Windows.Markup.XamlWriter.Save(temp, xmlwrite);
        return sb.ToString();
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク sasagaki 2013年11月24日 23:09
    2013年11月22日 13:06
  • gekkaさま

     丁寧に解説いただいてありがとうございました。

     テンプレートの取得方法、ならびにカスタマイズ方法がわかりました。

     どのようなテンプレートが利用されているかもプログラムで取得するのですね。

     ありがとうございました。

    2013年11月24日 23:08