Reputation: 355
public class EventLogView : UserControl
{
private DataGrid dataGrid;
public EventLogView()
{
this.InitializeComponent();
dataGrid = this.FindControl<DataGrid>("EventLogsDataGrid");
this.dataGrid.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid_LoadingRows);
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
void dataGrid_LoadingRows(object sender, DataGridRowEventArgs e)
{
}
}
I would like to change every row color to the red, if the 4th column's value is "HIGH".
Upvotes: 1
Views: 5089
Reputation: 11
There may be another way to do the same thing, but in XAML. To be honest, I don’t compete the quest, but it was really close. The author of Avalonia.Xaml.Behaviors Wiesław Šoltés has posted an example of a very interesting approach. I tried to adopt it for use with the DataGrid’s row and it almost worked:
<Window xmlns="https://github.com/avaloniaui"
xmlns:int="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
xmlns:ia="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"
x:Class="BvsDesktopLinux.Views.MainWindow" ...>
...
<Window.Styles>
<Style Selector="DataGridCell.statusColumn">
<Setter Property="FontSize" Value="24"/>
<Setter Property="(int:Interaction.Behaviors)">
<int:BehaviorCollectionTemplate>
<int:BehaviorCollection>
<ia:DataTriggerBehavior Binding="{Binding Status}" ComparisonCondition="Equal" Value="Rejected">
<ia:ChangePropertyAction TargetObject="DataGridCell" PropertyName="Background" Value="Red" />
</ia:DataTriggerBehavior>
</int:BehaviorCollection>
</int:BehaviorCollectionTemplate>
</Setter>
</Style>
</Window.Styles>
...
<DataGrid AutoGenerateColumns="False" Margin="10"
Items="{Binding Banknotes}" SelectedItem="{Binding SelectedBanknote}">
<DataGrid.Columns>
<DataGridTextColumn Header="{x:Static p:Resources.NoteId}" Binding="{Binding Id}" />
<DataGridTextColumn Header="{x:Static p:Resources.NoteCurrency}" Binding="{Binding Currency}" />
<DataGridTextColumn Header="{x:Static p:Resources.NoteDenomination}" Binding="{Binding Denomination}" />
<DataGridTextColumn Header="{x:Static p:Resources.Status}" Binding="{Binding Status}" CellStyleClasses="statusColumn" />
</DataGrid.Columns>
</DataGrid>
I only had one problem with the code – the binding doesn't use the DataGridCell's DataContext (the element of the ObservableCollection from the ViewModel), but it uses the DataContext of the whole View/Window (ViewModel).
Upvotes: 1
Reputation: 11
@mm8: Thanks for the useful hint! I was looking for the same answer and started with your advice. I ran into a problem after sorting the rows, or reloading the content with some modifications. Several rows that didn't match the criteria had the background property attached. So I used styles to attach/detach the style:
<Window.Styles>
<Style Selector="DataGridRow.rejectedStatus">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</Window.Styles>
private void DataGrid_OnLoadingRow(object? sender, DataGridRowEventArgs e)
{
var dataObject = e.Row.DataContext as Models.Banknote;
if (dataObject != null && dataObject.Status == "Rejected")
{
e.Row.Classes.Add("rejectedStatus");
}
else
{
e.Row.Classes.Remove("rejectedStatus");
}
}
Upvotes: 0
Reputation: 169330
The way to do this in "pure" WPF would be to define an ItemContainerStyle
with a DataTrigger
:
<DataGrid x:Name="EventLogsDataGrid"
AutoGenerateColumns="False"
Items="{Binding LogsData}"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
IsReadOnly="True">
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Importance}" Value="HIGH">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.ItemContainerStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}"
Header="ID"
Width="Auto"/>
<DataGridTextColumn Binding="{Binding Content}"
Header="Content"
Width="Auto"/>
<DataGridTextColumn Binding="{Binding CreationDate}"
Header="Date Time"
Width="Auto"/>
<DataGridTextColumn Binding="{Binding Source}"
Header="Source"
Width="Auto"/>
<DataGridTextColumn Binding="{Binding Importance}"
Header="Priority"
Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
But since Avalonia doesn't support triggers, you may have to handle the LoadingRow
event something like this to set the Background
property programmtically:
void dataGrid_LoadingRows(object sender, DataGridRowEventArgs e)
{
var dataObject = e.Row.DataContext as YourDataObject;
if (dataObject != null && dataObject.Importance == "HIGH")
e.Row.Background = Brushes.Red;
}
Upvotes: 1