how to change a row's style in WPF Datagrid?

孤街醉人 提交于 2019-12-05 02:51:58

问题


I am new to WPF, and need help in styling a specific row or rows in a datagrid in runtime, depending on some values of the stored data. I saw this thread but couldn't retrive my problem of row that exist only in runtime from columns that exist in design.

any example will be gladly accepted. thanks!

edited: I found this thread too, but I need a C# code...


回答1:


I can't tell from your question whether you are adding columns to your grid at run time, but either way you can add a CellStyle to the grid at design time that handles your specific styling needs using DataTriggers.

For instance, the following would make all rows red where the Name property = "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>

If you are adding columns programmatically at run time and you want to apply a certain style to them, you can still define those styles at design time in your xaml.

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

Then when you are adding the columns you can apply that style to them:

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

Update

If you have a list of songs and you want to change the row color of every song that has an artist whose name starts with an "a", then you could use an IValueConverter.

The following converter would do the trick:

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();
    }
}

Then you could use the converter in your xaml like so:

    <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>

Notice how I am passing an "a" into the converter as the parameter. You can pass in whatever letter you want, and the rows that have artists that start with that letter will have their background color set to red.

Update 2

If you want to pass in a variable of some sort to the converter, you can use MultiBinding.

The Converter would look like this:

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();
    }
}

The first parameter passed in is the artist name, the second is the letter.

And you would use it in your grid like this:

        <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>

In this example, the first letter is coming from the "Text" property of a control called "FirstLetter". You can change that binding to whatever you want.



来源:https://stackoverflow.com/questions/7122131/how-to-change-a-rows-style-in-wpf-datagrid

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!