none
スタイルの書き方について RRS feed

  • 質問

  • いつもお世話になっております。よろしくお願いします。

    DataGridのスタイルの書き方についてご教示ください。
    Trigger+DataTrigger両方の条件を満たした場合にスタイルを変更したいのですが、可能でしょうか?

    例)
    DataGrid内で、バインドしているデータが1で、かつIsSelectedがTrueの場合に
    背景色を赤色に変更する

    トリガーの複数条件については、下記Multi***というのがあるのは調べたのですが、
    両方を複合させた場合はどうすれば良いのか分かりませんでした。
    Trigger→MultiTrigger
    DataTrigger→MultiDataTrigger

    環境
    VisualStudio2010、WPF、C#、Livet
    2012年6月19日 9:49

回答

  • DataGridにバインドさせてるオブジェクトに選択中かどうかのフラグとか持たせて、DataGridRowのIsSelectedとバインドさせてMultiDataTriggerで判別できるようにしてもできます。

    // バインドさせるオブジェクト
    public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public bool IsSelected { get; set; }
    }
    

    XAMLでは、以下のような感じで。

    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" IsReadOnly="True">
        <DataGrid.ItemContainerStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding IsSelected}" Value="True" />
                            <Condition Binding="{Binding ID}" Value="10" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Background" Value="Red" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.ItemContainerStyle>
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        </DataGrid.Columns>
    </DataGrid>
    
    ポイントは、Styleの中でDataGridRowのIsSelectedとPersonクラスのIsSelectedをバインドしてる点になります。こうして、StyleのTriggersでMultiDataTriggerを使って選択中でIDが10の場合背景色を赤にするという設定をしています。


    かずき Blog:http://d.hatena.ne.jp/okazuki/

    • 回答としてマーク dar4301 2012年6月20日 0:10
    2012年6月19日 14:37
  • 普通には出来ないので、Tagとかの使わないプロパティを経由させたりします。

    <Style.Triggers>
        <DataTrigger Binding="{Binding}" Value="1">
            <Setter Property="Tag" Value="1" />
        </DataTrigger>
        
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Tag" Value="1" />
                <Condition Property="IsSelected" Value="True" />
            </MultiTrigger.Conditions>
            
            <Setter Property="Background" Value="Red" />
            
        </MultiTrigger>
    </Style.Triggers>

    (※ 分かってると思いますけど記述順注意です)

    ☆TFC Software http://www.tfc-software.com/
    ☆プログラミングに関するブログ http://www.tfc-software.com/Blogs.aspx

    • 回答としてマーク dar4301 2012年6月20日 0:10
    2012年6月19日 14:16

すべての返信

  • 普通には出来ないので、Tagとかの使わないプロパティを経由させたりします。

    <Style.Triggers>
        <DataTrigger Binding="{Binding}" Value="1">
            <Setter Property="Tag" Value="1" />
        </DataTrigger>
        
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Tag" Value="1" />
                <Condition Property="IsSelected" Value="True" />
            </MultiTrigger.Conditions>
            
            <Setter Property="Background" Value="Red" />
            
        </MultiTrigger>
    </Style.Triggers>

    (※ 分かってると思いますけど記述順注意です)

    ☆TFC Software http://www.tfc-software.com/
    ☆プログラミングに関するブログ http://www.tfc-software.com/Blogs.aspx

    • 回答としてマーク dar4301 2012年6月20日 0:10
    2012年6月19日 14:16
  • DataGridにバインドさせてるオブジェクトに選択中かどうかのフラグとか持たせて、DataGridRowのIsSelectedとバインドさせてMultiDataTriggerで判別できるようにしてもできます。

    // バインドさせるオブジェクト
    public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public bool IsSelected { get; set; }
    }
    

    XAMLでは、以下のような感じで。

    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" IsReadOnly="True">
        <DataGrid.ItemContainerStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding IsSelected}" Value="True" />
                            <Condition Binding="{Binding ID}" Value="10" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Background" Value="Red" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.ItemContainerStyle>
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        </DataGrid.Columns>
    </DataGrid>
    
    ポイントは、Styleの中でDataGridRowのIsSelectedとPersonクラスのIsSelectedをバインドしてる点になります。こうして、StyleのTriggersでMultiDataTriggerを使って選択中でIDが10の場合背景色を赤にするという設定をしています。


    かずき Blog:http://d.hatena.ne.jp/okazuki/

    • 回答としてマーク dar4301 2012年6月20日 0:10
    2012年6月19日 14:37
  • Tetsuaki Uchida様、かずき_okazuki様

    返信ありがとうございます。

    なるほど、やり方によってMultiTriggerでもMultiDataTriggerでもいいんですね。
    考えつきませんでした。勉強になりました。ありがとうございます!
    2012年6月20日 0:25