データバインディングを使用してプロパティ値に基づいて、DataGridの行の背景を設定する方法


81

XAMLコードでBackgroundは、特定の1つの行のオブジェクトの値に基づいて、各行の色を設定したいと思います。私が持っているObservableCollectionのをz、とのそれぞれは、zというプロパティを持っていますState。私は私の中でこのようなものから始めましたDataGrid

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Background" 
                Value="{Binding z.StateId, Converter={StaticResource StateIdToColorConverter}}"/>
     </Style>
</DataGrid.RowStyle>

xは私のViewModelクラスのプロパティではないため、これは間違ったアプローチです。

私のViewModelクラスでは私が持ってObservableCollection<z>いるどのItemsSource本のDataGrid、およびSelectedItemタイプのをz

色をSelectedItemにバインドすることはできますが、これはの1行のみを変更しDataGridます。

1つのプロパティに基づいて、この行の背景色を変更するにはどうすればよいですか?

回答:


171

を使用してくださいDataTrigger

<DataGrid ItemsSource="{Binding YourItemsSource}">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow"> 
            <Style.Triggers>
                <DataTrigger Binding="{Binding State}" Value="State1">
                    <Setter Property="Background" Value="Red"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding State}" Value="State2">
                    <Setter Property="Background" Value="Green"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

2
次のメッセージしか表示されません:BindingExpressionパスエラー:'State' property not found on 'object' ''z' (HashCode=7162954)'. BindingExpression:Path=State; DataItem='z' (HashCode=7162954); target element is 'DataGridRow' (Name=''); target property is 'NoTarget' (type 'Object')エンティティがこれを保持しているときにプロパティの状態が見つからず、データベースに状態が列として表示されるのはなぜですか?
Tobias Moe Thorstensen 2013

2
私はあなたがそれをとしてやっていないことを望みますz.State
Nitesh 2013

4
wpfから離れた後、これに再び遭遇しました。もう一度賛成できたらいいのにと思います。
リック2014

5
これは素晴らしい。それを使用したソリューションでは、enum値に基づいて状態を変更する必要がありました。StackOverflowでのこの回答は、私を助けてくれました。
kaspermoerch 2015年

バインドするプロパティが必要であることを忘れないでくださいpublic
CAD bloke 2017年

17

同じことがなくてDataTriggerも行うことができます:

 <DataGrid.RowStyle>
     <Style TargetType="DataGridRow">
         <Setter Property="Background" >
             <Setter.Value>
                 <Binding Path="State" Converter="{StaticResource BooleanToBrushConverter}">
                     <Binding.ConverterParameter>
                         <x:Array Type="SolidColorBrush">
                             <SolidColorBrush Color="{StaticResource RedColor}"/>
                             <SolidColorBrush Color="{StaticResource TransparentColor}"/>
                         </x:Array>
                     </Binding.ConverterParameter>
                 </Binding>
             </Setter.Value>
         </Setter>
     </Style>
 </DataGrid.RowStyle>

BooleanToBrushConverter次のクラスはどこにありますか。

public class BooleanToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Brushes.Transparent;

        Brush[] brushes = parameter as Brush[];
        if (brushes == null)
            return Brushes.Transparent;

        bool isTrue;
        bool.TryParse(value.ToString(), out isTrue);

        if (isTrue)
        {
            var brush =  (SolidColorBrush)brushes[0];
            return brush ?? Brushes.Transparent;
        }
        else
        {
            var brush = (SolidColorBrush)brushes[1];
            return brush ?? Brushes.Transparent;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

さらに優れているのは、IMultiValueConverter(docs.microsoft.com/en-us/dotnet/api/…)を適用して、複数のプロパティをバインドし、コンバーターがそれらの複数のプロパティの状態に対して正しい色を返すようにすることです(省略します)。サンプルは通常のコンバーターの場合と
非常に

7

XAMLで、行背景を従業員オブジェクトで定義されに設定することを目的として、DataGridのRowStyleプロパティを追加および定義します

<DataGrid AutoGenerateColumns="False" ItemsSource="EmployeeList">
   <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
             <Setter Property="Background" Value="{Binding ColorSet}"/>
        </Style>
   </DataGrid.RowStyle>

そして私の従業員クラスで

public class Employee {

    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public string ColorSet { get; set; }

    public Employee() { }

    public Employee(int id, string name, int age)
    {
        Id = id;
        Name = name;
        Age = age;
        if (Age > 50)
        {
            ColorSet = "Green";
        }
        else if (Age > 100)
        {
            ColorSet = "Red";
        }
        else
        {
            ColorSet = "White";
        }
    }
}

この方法では、すべてのDataGridの行があり、背景色ColorSet 私のオブジェクトのプロパティを


オブジェクトの色がビューではなくモデル自体に集中するため、この方法が好きです。
ΩmegaMan

1
これがMVVMに違反することを除いて。あなたが気にしないなら、それを持ってください。ただし、ユーザーエクスペリエンスはモデルによって決定されるべきではありません。それがビュー/ビューモデルの仕事です
BrianVPS 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.