I'm trying to do a simple example of a datatrigger programmatically in C# and don't get how it works. The datatrigger in XAML would work but I need it in C#. The rows in the datagrid should change their color if the number is 10.
My MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<User> users = new List<User>();
users.Add( new User() { Id = 1, Name = "John Doe", Number = 1 } );
users.Add( new User() { Id = 2, Name = "Jane Doe", Number = 10 } );
users.Add( new User() { Id = 3, Name = "Sammy Doe", Number = 10 } );
users.Add( new User() { Id = 4, Name = "Anne Blanc", Number = 7 } );
dgUsers.ItemsSource = users;
}
}
public class User //: INotifyPropertyChanged
{
public int Id
{
get; set;
}
public string Name
{
get; set;
}
// must be implemented as dependency property?
//private int _number;
public int Number
{
get; set;
//get
//{
// return _number;
//}
//set
//{
// _number = value;
// OnPropertyChanged( "Number" );
//}
}
//public event PropertyChangedEventHandler? PropertyChanged;
//public void OnPropertyChanged( string propName )
//{
// PropertyChangedEventHandler handler = PropertyChanged;
// if ( handler != null )
// handler( this, new PropertyChangedEventArgs( propName ) );
//}
}
And this simple datatrigger in MainWindow.xaml works:
<Window x:Class="WpfGrid1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfGrid1"
mc:Ignorable="d"
Title="DataGridColumnsSample" Height="500" Width="500">
<Grid Grid.Column="0" Margin="10">
<DataGrid Name="dgUsers" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="100" />
<DataGridTextColumn Header="Number" Binding="{Binding Number}" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Number}" Value="10">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
</Window>
Do I need to implement the interface INotifyPropertyChanged even if it works without it in XAML? I tried to implement it (see class User above).
But I don't understand how to set the binding if I create the trigger programmatically in the C# code and not in the XAML file. My attempts (before or after the line dgUsers.ItemsSource = users;
) were:
//this.DataContext = dgUsers.ItemsSource;
Binding bindingObjectNumber = new Binding();
//bindingObjectNumber.Mode = BindingMode.OneWay; // update target if source changes
bindingObjectNumber.Mode = BindingMode.TwoWay;
//bindingObjectNumber.Source = dgUsers;
//bindingObjectNumber.Source = dgUsers.ItemsSource;
bindingObjectNumber.Source = users;
bindingObjectNumber.Path = new PropertyPath( "Number" );
//bindingObjectNumber.RelativeSource = RelativeSource.Self;
DataTrigger dataTrigger = new DataTrigger();
dataTrigger.Binding = bindingObjectNumber;
dataTrigger.Value = "10";
dataTrigger.Setters.Add( new Setter( DataGrid.ForegroundProperty, Brushes.Red ) );
Style style = new Style();
style.Triggers.Add( dataTrigger );
this.Resources.Add( typeof( DataGrid ), style );
These links didn't help me as an absolute beginner in WPF.
- Simple DataTrigger not Working. Why?
- How to create a DataTrigger programatically with Binding="{Binding}"?
- https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/binding-declarations-overview?view=netdesktop-6.0
Any help or explanation would be appreciated. Thank you very much.
CodePudding user response:
dgUsers.RowStyle = new Style
{
TargetType = typeof(DataGridRow),
Triggers =
{
new DataTrigger
{
Binding = new Binding("Number"),
Value = 10,
Setters =
{
new Setter( DataGrid.ForegroundProperty, Brushes.Red )
}
}
}
};