How to set color for first row in Datagrid

2019-06-11 21:19发布

问题:

I have a datagrid on a wpf (mvvm) project. the datagrid sort is showing the last item added to the collection as the first row. i want to color the first row (in order to highlight new item added to the collection) I've seen some similar questions about this manner but none of them are really related to what i am looking for. i have tried to use a IValueConverter but it doesnt seems to be the right path for me as i need to get a unique identifier for the first row and change all the rest of the rows in order to classified it as a "First Row".

my object model for the items in the collection looks like this:

public class Messages
{
    public string Date {get; set;}
    public string Sender{get; set;}
    public string Content{get; set;}
} 

*EDIT Forgot to add the converter code... of course this will color all rows to red, as i dont know how to affect the other rows when the collection changes.

class DateToColorConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (Convert.ToDateTime(value) >= DateTime.Now.AddMinutes(-1))
        {
            return "Red";
        }
        else
            return "Yellow";
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

回答1:

You can use RelativeSource with Mode set to PreviousData to identify whether dataGrid row is first one or not. For first row PreviousData will return null.

Apply DataTrigger on DataGridRow in ItemContainerStyle:

<DataGrid>
    <DataGrid.ItemContainerStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="LightBlue"/>
            <Style.Triggers>
                <DataTrigger
                  Binding="{Binding RelativeSource={RelativeSource Mode=PreviousData}}"
                  Value="{x:Null}">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.ItemContainerStyle>
</DataGrid>


回答2:

You could do a simple solution if your data classes use some sort of an Id field. Let's say that newly added objects have an Id of -1, or 00000000-0000-0000-0000-000000000000 (to be updated/set upon a successful save). In this case, you could use a simple DataTrigger to change the Background of these items:

<DataTemplate DataType="{x:Type YourPrefix:Message}">
    <Border>
        <!--Define your Message UI here-->
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Setter Property="Background" Value="{StaticResource YourNormalBrush}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Id}" Value="-1">
                        <Setter Property="Background" Value="{StaticResource YourHighlightBrush}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
    </Border>
</DataTemplate>


回答3:

Add a bool to your Model that will indicate the last element added :

    public class Messages
{
    public string Date {get; set;}
    public string Sender{get; set;}
    public string Content{get; set;}
    public string IsNew {get; set;}

} 

and set the style of the DataGridRow based on that Property :

<Window.Resources>       
        <Style x:Key="DataGridRowStyle" TargetType="DataGridRow">
            <Setter Property="Background" Value="Blue"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsNew}" Value="True">
                    <Setter Property="Background" Value="Red"></Setter>
                </DataTrigger>

            </Style.Triggers>
        </Style>
    </Window.Resources>

In code above the blue will be the default style and the Red is for the new Rows

 <DataGrid ItemsSource="{Binding DataGridItems}" RowStyle="{StaticResource DataGridRowStyle}" AutoGenerateColumns="True">               
        </DataGrid>