如何根据行数据动态更改行样式

本文关键字:样式 动态 数据 何根 | 更新日期: 2023-09-27 18:06:21

如何在运行时期间在WPF Datagrid中设置特定的行或行?每次更改都取决于所显示数据的某些值。

如何根据行数据动态更改行样式

我不能从你的问题中知道你是否在运行时向网格添加列,但无论哪种方式,你都可以在设计时向网格添加CellStyle,使用DataTriggers处理你的特定样式需求。

例如,下面将使Name属性= "Billy Bob"的所有行都为红色:

    <DataGrid AutoGenerateColumns="True" Name="dataGrid1">
        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Name}" Value="Billy Bob" >
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>

如果您在运行时以编程方式添加列,并且希望对它们应用特定的样式,您仍然可以在设计时在xaml中定义这些样式。

    <DataGrid AutoGenerateColumns="False" Name="dataGrid1">
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridCell}" x:Key="MyCellStyle">
                <Setter Property="Foreground" Value="Green"/>
            </Style>
        </DataGrid.Resources>
        ...

然后当你添加列时,你可以将该样式应用到它们:

col.CellStyle = (Style)dataGrid1.Resources("MyCellStyle");

如果你有一个歌曲列表,你想改变每首歌曲的行颜色,其中有一个歌手的名字以"a"开头,那么你可以使用IValueConverter。

下面的转换器可以做到这一点:

public class ArtistNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        try
        {
            return value.ToString().StartsWith(parameter.ToString());
        }
        catch
        {
            return false;
        }
    }
    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后你可以像这样在你的xaml中使用转换器:

    <DataGrid AutoGenerateColumns="True" Name="dataGrid1">
        <DataGrid.Resources>
            <converters:ArtistNameConverter x:Key="ArtistNameConverter"></converters:ArtistNameConverter>
        </DataGrid.Resources>
        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ArtistName, Converter={StaticResource ArtistNameConverter}, ConverterParameter=a}" Value="True" >
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>

注意我是如何将"a"作为参数传递给转换器的。你可以传入任何你想要的字母,并且以该字母开头的艺术家的行背景色将被设置为红色。

更新2

如果你想传递某种类型的变量给转换器,你可以使用MultiBinding。

转换器看起来像这样:

public class ArtistNameConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, 
        System.Globalization.CultureInfo culture)
    {
        try
        {
            return values[0].ToString().StartsWith(values[1].ToString());
        }
        catch
        {
            return false;
        }
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, 
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

传入的第一个参数是艺术家的名字,第二个参数是字母。

你可以像这样在你的网格中使用它:

        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}">
                <Style.Triggers>
                    <DataTrigger Value="True" >
                        <DataTrigger.Binding>
                            <MultiBinding Converter="{StaticResource ArtistNameConverter}">
                                <Binding Path="ArtistName" />
                                <Binding Mode="OneWay" ElementName="FirstLetter" Path="Text" />
                            </MultiBinding>
                        </DataTrigger.Binding>
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>

在这个例子中,第一个字母来自控件"FirstLetter"的"Text"属性。