Introduction
Hi this article demonstrates how to create a DataGridColumn at run time with Styles and Triggers. Normally at design time when we create a DataGrid, we also create the required columns or set the autogenareted column property of the DataGrid to true to create automatically generate the columns based on the bound item source. Suppose you need to create a DataGrid without knowing how many columns you to need to create and you don't know the columns names with their binding value and other properties like cell background color and so on.
In the preceding case this article will help you. This article creates a DatagridColumn at runtime having other properties, like header, cell style, Trigger and so on.
In this article we will learn the following points:
- Creating DataGrid Column at runtime and assign to DataGrid.
- Binding property name with DataGrid column to display a property value in the DataGrid cell
- Adding cell style in the DataGrid at runtime
- Adding trigger into DataGrid at runtime
To create a DataGridColumn at run time you will require the following namespaces. These namespaces help to create controls, binding (required to bind a property with a DataGrid cell), Styles, Triggers and so on.
- System.Windows.Controls
- System.Windows.Data
- System.Windows
1. Creating DataGridColumn
2. Bind property
At design time we are creating DataGridColumns like DataGridTextColumn using XAML like the following code.
- <DataGrid x:Name="dgvRates">
- <DataGrid.Columns >
- <DataGridTextColumn Binding="{Binding Path=xyz, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header=" XYZ " MinWidth="110">
- </DataGridTextColumn>
- </DataGrid>
- //creates object of datagridtextcolum class
- DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
- // sets header name
- dataGridTextColumn.Header = “XYZ”;
- //creates object of binding class , accepts name of property as parameter , whose value to be display
- Binding binding = new Binding(“PropertyName”);
- // sets binding mode
- binding.Mode = BindingMode.TwoWay;
- // sets how trigger to be fired.
- binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- // assigned the object of binding class to object of datagridtextcolumn class;
- dataGridTextColumn.Binding = binding;
- // added created column into column list of datagrid (dgvRates);
- dgvRates.Columns.Add(dataGridTextColumn);
3. Adding cell style in the DataGrid at runtime
At the design time, to apply a style to the datagrid cell, for example foreground and background colors, we are doing the following XAML code.
- <DataGridTextColumn.CellStyle>
- <Style TargetType="{x:Type DataGridCell}">
- <Setter Property="Background" Value="{Binding Brushes.Black}" />
- <Setter Property=" Foreground " Value="{Binding Brushes.White}" />
- </Style>
- </DataGridTextColumn.CellStyle>
But if we want to set colors with the DataGrid cell at runtime then we are binding the foreground and background properties with a property of datacontext or with a control's background or foreground property like the following XAML code:
- <DataGridTextColumn.CellStyle>
- <Style TargetType="{x:Type DataGridCell}">
- <Setter Property="Foreground" Value="{Binding Background, ElementName=txtFont, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
- <Setter Property="Background" Value="Binding Background, ElementName=txtBackground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
- </Style>
- </DataGridTextColumn.CellStyle>
In the code above the foreground of the DataGrid is set from the background property of the TextBox having the name txtfont and the background is set from the background property of the TextBox txtBackground. The binding mode is two-way because when the background changes both the text box of the cell background and foreground will be changed automatically.
To add the cell style at runtime as in the preceding XAML code, you will need to use the style and setter class that comes under the System.Windows namespace. This class will help you to set the background, font style and Add trigger and so on. A style consists of a list of setters. If you apply this style to an element it sets all properties with the specified values. The idea is quite similar to Cascading Styles Sheets (CSS) that we are familiar with from web development. The following code accomplishes the same thing that is specified in the preceding XAML code.
- Style style = new Style(); // creates object of style class
- style.TargetType = typeof(DataGridCell); sets target type as DataGrid cell
- Setter setterBackground = new Setter(); // create objects of setter class
- setterBackground.Property = DataGridCell.BackgroundProperty;
- setterBackground.Value = Brushes.Green;
- style.Setters.Add(setterBackground);
- dataGridTextColumn.CellStyle = style;
4. Adding trigger into DataGrid at runtime
We require triggers when we want something to change when something happens in the application. For example we want the background color of a DataGrid cell to change when a value changes that meets a specific criteria. This article has explained how to add a data trigger to a DataGridcell to change the background color.
At design time, to add a data trigger with a DataGrid, we are doing code in XAML like the following code:
- DataGridTextColumn.CellStyle>
- <Style TargetType="{x:Type DataGridCell}">
- <Style.Triggers>
- <DataTrigger Binding="{Binding, UpdateSourceTrigger=PropertyChanged}" Value="<=100">
- <Setter Property="Background" Value="{Binding Brushes.Red, UpdateSourceTrigger=PropertyChanged}" />
- </DataTrigger>
- <DataTrigger Binding="{Binding, UpdateSourceTrigger=PropertyChanged}" Value="<=200">
- <Setter Property="Background" Value="{Binding Brushes.Black, UpdateSourceTrigger=PropertyChanged}" />
- </DataTrigger>
- <DataTrigger Binding="{Binding, UpdateSourceTrigger=PropertyChanged}" Value=">200">
- <Setter Property="Background" Value="Binding Brushes.Green"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </DataGridTextColumn.CellStyle>
In the preceding XAML code if the DataGrid cell value is greater or equal to 100 then the cell background color is read and if <= 200 then Black or > 200 then Green. Now we will do the same thing using C# code. We will need a datatrigger class from the System.Window.Data namespace. See the following C# code that is doing that as XAML.
- Style style = new Style();
- style.TargetType = typeof(DataGridCell);
- DataTrigger DT = new DataTrigger();
- Binding DataTriggerBinding = new Binding( “bindingName1”);
- DataTriggerBinding.Mode = BindingMode.Default;
- DataTriggerBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- DT.Binding = DataTriggerBinding;
- DT.Value = “<=100”;
- Setter DataTriggerSetter = new Setter();
- DataTriggerSetter.Property = DataGridCell.BackgroundProperty;
- DataTriggerSetter.Value = Brushes.Red;
- DT.Setters.Add(DataTriggerSetter);
- style.Triggers.Add(DT);
- DataTrigger DT1 = new DataTrigger();
- Binding DataTriggerBinding1 = new Binding(“bindingName2”);
- DataTriggerBinding1.Mode = BindingMode.Default;
- DataTriggerBinding1.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- DT1.Binding = DataTriggerBinding;
- DT1.Value = “<=200”;
- Setter DataTriggerSetter1 = new Setter();
- DataTriggerSetter1.Property = DataGridCell.BackgroundProperty;
- DataTriggerSetter1.Value = Brushes.Black;
- DT1.Setters.Add(DataTriggerSetter1);
- style.Triggers.Add(DT1);
- DataTrigger DT2 = new DataTrigger();
- Binding DataTriggerBinding2 = new Binding(“bindingName3”);
- DataTriggerBinding2.Mode = BindingMode.Default;
- DataTriggerBinding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
- DT2.Binding = DataTriggerBinding2;
- DT2.Value = “<=100”;
- Setter DataTriggerSetter2 = new Setter();
- DataTriggerSetter2.Property = DataGridCell.BackgroundProperty;
- DataTriggerSetter2.Value = Brushes.Red;
- DT2.Setters.Add(DataTriggerSetter2);
- style.Triggers.Add(DT2);
- dataGridTextColumn.CellStyle = style;
-
//creates object of datagridtextcolum classDataGridTextColumn dataGridTextColumn = new DataGridTextColumn();// sets header namedataGridTextColumn.Header = "Dynamic Column";//creates object of binding class , accepts name of property as parameter , whose value to be displayBinding binding = new Binding("PropertyName");// sets binding modebinding.Mode = BindingMode.TwoWay;// sets how trigger to be fired.binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;// assigned the object of binding class to object of datagridtextcolumn class;dataGridTextColumn.Binding = binding;//code for add style to rowStyle Rowstyle = new Style(); // creates object of style classRowstyle.TargetType = typeof(DataGridRow);//sets target type as DataGrid rowSetter setterBackground = new Setter(); // create objects of setter classsetterBackground.Property = DataGridRow.BackgroundProperty;setterBackground.Value = Brushes.Black;Rowstyle.Setters.Add(setterBackground);Setter setterForeGround = new Setter();setterForeGround.Property = DataGridRow.ForegroundProperty;setterForeGround.Value = Brushes.White;Rowstyle.Setters.Add(setterForeGround);dgvRate.RowStyle = Rowstyle;Style DataGridCellStyle = new Style();DataGridCellStyle.TargetType = typeof(DataGridCell);DataTrigger DT = new DataTrigger();Binding DataTriggerBinding = new Binding("bindingName");DataTriggerBinding.Mode = BindingMode.Default;DataTriggerBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;DT.Binding = DataTriggerBinding;DT.Value = "<=100";Setter DataTriggerSetter = new Setter();DataTriggerSetter.Property = DataGridCell.BackgroundProperty;DataTriggerSetter.Value = Brushes.Red;DT.Setters.Add(DataTriggerSetter);DataGridCellStyle.Triggers.Add(DT);DataTrigger DT1 = new DataTrigger();Binding DataTriggerBinding1 = new Binding("bindingName");DataTriggerBinding1.Mode = BindingMode.Default;DataTriggerBinding1.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;DT1.Binding = DataTriggerBinding;DT1.Value = "<=200";Setter DataTriggerSetter1 = new Setter();DataTriggerSetter1.Property = DataGridCell.BackgroundProperty;DataTriggerSetter1.Value = Brushes.Black;DT1.Setters.Add(DataTriggerSetter1);DataGridCellStyle.Triggers.Add(DT1);DataTrigger DT2 = new DataTrigger();Binding DataTriggerBinding2 = new Binding("bindingName");DataTriggerBinding2.Mode = BindingMode.Default;DataTriggerBinding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;DT2.Binding = DataTriggerBinding2;DT2.Value = ">=200";Setter DataTriggerSetter2 = new Setter();DataTriggerSetter2.Property = DataGridCell.BackgroundProperty;DataTriggerSetter2.Value = Brushes.Red;DT2.Setters.Add(DataTriggerSetter2);DataGridCellStyle.Triggers.Add(DT2);dataGridTextColumn.CellStyle = DataGridCellStyle;// added created column into column list of datagrid (dgvRates);dgvRate.Columns.Add(dataGridTextColumn);
-
Lucy ParryPosted Jan 19, 2018, 12:00 PM
THANK YOU - I've been trawling Stack Overflow for how to do this for hours!