Columns
This section explains you how to add Columns, ways to create Column, different types of Column, and Column’s features like Column Sizer, Hiding, Freezing, Resizing Columns, and Drag and Drop support.
Add Columns
The SfDataGrid control allows you to add Columns in two ways:
- Automatically generate the Columns based on the underlying collection.
- Manually define the columns in XAML or C#.
Automatically Generate Columns
The following is a list of properties associated with generating columns.
SfDataGrid.AutoGenerateColumns: This dependency property decides Columns generation for a SfDataGrid based on AutoGenerateColumnsMode property.
SfDataGrid.AutoGenerateColumnsMode: It decides a way to create columns when AutoGenerateColumns is set to ‘true’. This enum type has the following four options.
- Reset: Creates columns for all fields in a Data Source and retains the columns defined explicitly in application level.
- RetainOld: Creates columns for all fields in a Data Source when the SfDataGrid does not have any explicit definition for columns. When columns are defined explicitly, then new columns are not created.
- ResetAll: When changing ItemsSource, the columns for previous data are cleared and it creates new columns. Else when you define columns explicitly it does not take defined columns, it takes from underlying collection.
- None: Stores the columns that are defined in DataGrid.Columns.
The SfDataGrid control by default creates columns for every public property automatically based on the underlying collection that bounds to the SfDataGrid using ItemsSource property. In this case, AutoGenerateColumns property value is set to ‘true’ and AutoGenerateColumnsMode property value is AutoGenerateColumnsMode.Reset.
NOTE
when you change items source for SfDataGrid during run time, then the columns are generated on the basis of option set for AutoGenerateColumns Mode.
The following is the event that is associated with AutoGeneratingColumns.
AutoGeneratingColumn Event
This event rises when the AutoGenerateColumns property values is set to ‘true’. This event receives two arguments namely sender that handles SfDataGrid and AutoGeneratingColumnArgs as objects.
The AutoGeneratingColumnArgs object contains the following property:
- Column: This property returns created column when AutoGenerateColumns is set to ‘true’. By using this property, you can manipulate columns.
- Cancel: This property cancels the columns to be created.
You can use this event where you want to manipulate columns (apply filtering, sorting, grouping, editing, header text) when AutoGenerateColumns is set to ‘true’.
DataAnnotation with AutoGenerateColumns
SfDataGrid supports DataAnnotations for customizing columns, when AutoGenerateColumns set to ‘true’. When DisplayAttribute, DataTypeAttribute, EditableAttribute and BindableAttribute are specified in model class, columns are generated based on the mentioned attributes that supports DataAnnotation of SfDataGrid.
NOTE
When AutoGenerateColumns property value is set to ‘false’, you can ignore mentioned DataAnnotations attributes.
The following example illustrates this scenario. For data collection use OrderInfoRepository.cs, file.
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumns="True"
ColumnSizer="Star"
ItemsSource="{Binding OrderInfoCollection,
Source={StaticResource data}}" />
In the following code example Display keyword mentions different attributes to customize columns.
public class OrderInfo
{
int orderID;
string customerId;
string country;
string customerName;
string shippingCity;
[Display(AutoGenerateField= false,Description="This filed is not created")]
[DataType(DataType.Currency)]
public int OrderID
{
get { return orderID; }
set { orderID = value; }
}
[Display(Order = -1, Description ="This field is hidden")]
public string CustomerID
{
get { return customerId; }
set { customerId = value; }
}
public string CustomerName
{
get { return customerName; }
set { customerName = value; }
}
[Display(AutoGenerateFilter = true)]
[Editable(true)]
public string Country
{
get { return country; }
set { country = value; }
}
[Display(Order = -2)]
public string ShipCity
{
get { return shippingCity; }
set { shippingCity = value; }
}
public OrderInfo(int orderId, string customerName, string country, string
customerId, string shipCity)
{
this.OrderID = orderId;
this.CustomerName = customerName;
this.Country = country;
this.CustomerID = customerId;
this.ShipCity = shipCity;
}
}
The following screenshot renders you the output.
You can see that in Country column it has Filtering enabled in its header.Since AutoGenerateFilter is set to ‘true’, ShipCity have order -2 that displays before CustomerID. When AutoGenerateField is set to ‘false’, OrderID column is not displayed
Manually Generate Columns
As mentioned in the second case, the SfDataGrid control enables you to define columns you want to display in the Grid. You can define the columns by adding a column to the SfDataGrid.Columns collection. The case where you want only the columns manually defined in view, you can set AutoGenerateColumns property value to ‘false’.
There are different GridColumns available in SfDataGrid.you can select any column as follows,
- GridTextColumn
- GridNumericColumn
- GridCurrencyColumn
- GridPercentColumn
- GridMaskColumn
- GridTimeSpanColumn, etc.
Each column has its own property to show its uniqueness in view and edit mode.
The following code example defines manually to create columns using XAML.
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumns="False"
ColumnSizer="Auto"
ItemsSource="{Binding OrderInfoCollection}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn HeaderText="Order ID" MappingName="OrderID" />
<syncfusion:GridTextColumn HeaderText="Customer ID" MappingName="CustomerID" />
<syncfusion:GridTextColumn HeaderText="Name of Customer" MappingName="CustomerName" />
<syncfusion:GridTextColumn HeaderText="Ship Country" MappingName="ShipCountry" />
<syncfusion:GridTextColumn HeaderText="Ship City" MappingName="ShipCity" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
The following code example defines manually create columns through C#.
void dataGrid_Loaded(object sender, RoutedEventArgs e)
{
dataGrid.Columns.Add(new GridTextColumn() { MappingName = "OrderID" });
dataGrid.Columns.Add(new GridTextColumn() { MappingName= "CustomerID"});
dataGrid.Columns.Add(new GridTextColumn() { MappingName = "CustomerName" });
dataGrid.Columns.Add(new GridTextColumn() { MappingName = "Country" });
dataGrid.Columns.Add(new GridTextColumn() { MappingName = "ShipCity" });
}
NOTE
The case where you want to display column in both ways: you can use SfDataGrid.AutoGenerateColumnsMode to define columns collection and remaining from items Source.
Column Properties
GridColumn is the base column type of all the columns in the SfDataGrid. The most important GridColumn properties are listed in the following table:
Property | Type | Description | Default Value |
---|---|---|---|
GridColumn.ActualWidth | Double | Determines the actual width of the Grid columns. | Double.NaN |
GridColumn.AllowBlankFilters | Boolean | Specifies whether blank filters are allowed in Excel-like filter drop-down list or not. | True |
GridColumn.AllowDragging | Boolean | Specifies whether the columns are allowed to drag in the SfDataGrid or not. | False |
GridColumn.AllowEditing | Boolean | Specifies whether the column is edited or not. | True |
GridColumn.AllowFiltering | Boolean | Specifies whether particular column is filtered or not. | False |
GridColumn.AllowFocus | Boolean | Specifies whether focus is allowed to a particular column or not. | True |
GridColumn.AllowGrouping | Boolean | Specifies whether columns are allowed to group in the SfDataGrid or not. | True |
GridColumn.AllowResizing | Boolean | Specifies whether the columns are allowed to be resized or not. | False |
GridColumn.AllowSorting | Boolean | Specifies whether sorting is allowed in a Grid Column or not. | True |
GridColumn.CellStyle | Style | Customizes the style for cells in the Grid Column. | Null |
GridColumn.ColumnFilter | ColumnFilter | Specifies how column data should be filtered based on Value or DisplayText in the Advanced Filtering. | Value |
GridColumn.ColumnSizer | Enum | Specifies the size of each column. Based on bound enum in ColumnSizer the width of the Grid Column is displayed. | None |
GridColumn.DisplayBinding | Binding | The Mapping Name that is bounded to Display Binding in a view mode of Grid Column that shows value with format. | Null |
GridColumn.FilterPopupStyle | Style | Customizes the style for Filter Pop-up. | Null |
GridColumn.FilterPopupTemplate | DataTemplate | Gets or sets and customizes the structure of the Filter Pop-up. | Null |
GridColumn.HeaderStyle | Style | Gets or sets and customizes the style for the header cell. | Null |
GridColumn.HeaderTemplate | DataTemplate | Gets or sets and customizes the structure of the Header cell. | Null |
GridColumn.HeaderText | String | The string value that is bounded to the Header text is displayed in Column header. | Null |
GridColumn.HeaderToolTipTemplate | DataTemplate | Customizes the structure of tooltip for header cell. | Null |
GridColumn.HorizontalHeaderContentAlignment | HorizontalAlignment | Sets horizontal alignment for the column header text. | HorizontalAlignment.Left |
GridColumn.ImmediateUpdateColumnFilter | Boolean | Specifies whether the filters are applied immediately when the checkbox is toggled in the filter pop-up list. | False |
GridColumn.IsHidden | Boolean | The property that allows the column to be hidden. | False |
GridColumn.MappingName | String | The property from ItemsSource that is bounded to the Mapping Name gives its loaded data in view. | Null |
GridColumn.MaximumWidth | Double | Specifies the maximum width of the Grid Column. | Double.NaN |
GridColumn.MinimumWidth | Double | Specifies the minimum width of the Grid Column. | Double.NaN |
GridColumn.Padding | Thickness | Specifies the padding thickness for the column’s cell. | (5,1,5,1) |
GridColumn.ToolTipTemplate | DataTemplate | The property that customizes the tooltip. | Null |
GridColumn.UseBindingValue | Boolean | When set to ‘true’, the value that is bounded to ValueBinding is used in the Excel-like filter pop-up list. | False |
GridColumn.GridValidationMode | GridValidationMode | Specifies the validation mode for GridColumn | None |
GridColumn.ValueBinding | Binding | Specifies the binding for GridColumns when the GridCell is in edit mode. The basic operations are handled on the data that is bounded to value binding property. | Null |
GridColumn.Width | Double | Determines the width of the Grid Column. | Double.NaN |
NOTE
GridTextColumnBase is the abstract class that is derived from GridColumn. GridTextColumn, GridNumericColumn and GridDateTimeColumn are derived from GridTextColumnBase. GridComboBoxColumn, GridImageColumn, GridTemplateColumn and GridHyperlinkColumn derived from the GridColumn.
The following provides the list of properties that supports the columns having GridTextColumnBase as Base Class.
Property | Type | Description | Default Value |
---|---|---|---|
GridTextColumnBase.TextTrimming | TextTrimming | The property trims the value in each cell of the column that has more length than column width in view. | TextTrimming.None |
GridTextColumnBase.TextWrapping | TextWrapping | The property trims the value in each cell of the column that has more length than column width in edit. | TextWrapping. NoWrap |
GridTextColumnBase. TextDecorations | TextDecorations | The property that customizes the text. | new TextDecorationCollection() |
CellTemplate
CellTemplate support is used to customize columns in display mode that present cells with DataTemplate. You can load standard controls or customized control in display mode to all columns like template column. In edit mode GridColumn loads it default editor.
Property | Description | Type | Default Value |
---|---|---|---|
CellTemplate | The dependency property that gets or sets the data template of cell in display mode. | DataTemplate | Null |
CellTemplateSelector | The dependency property that gets or sets the DataTemplateSelector and apply the defined template to cell in display. | DataTemplateSelector | Null |
SetCellBoundValue | The DataContext for DataTemplate is set based on this property that sets the Record as DataContext. When setting this to true, it sets DataContextHelper as DataContext. DataContextHelper has Value and Record properties where the Value is set based on MappingName of the column. | bool | False |
The following code example illustrates that how to set CellTemplate in Numeric Column.
<syncfusion:GridNumericColumn FormatString="c"
MappingName="Freight"
Padding="5">
<syncfusion:GridNumericColumn.CellTemplate>
<DataTemplate>
<Grid>
<ProgressBar x:Name="progressBar" Background="Transparent" Visibility="Visible" BorderThickness="0" Maximum="1000" Height="40" Value="{Binding Freight}" Width="120"/>
<TextBlock Text="{Binding Freight}" HorizontalAlignment="Right"
VerticalAlignment="Center" TextAlignment="Right"/>
</Grid>
</DataTemplate>
</syncfusion:GridNumericColumn.CellTemplate>
</syncfusion:GridNumericColumn>
The above XAML code renders the following output.
When you use CellTemplate for all columns, you can define DataTemplate at once and can bind to different columns with the underlying data to the DataTemplate regardless of MappingName. The property that allows to reuse the DataTemplate to any number of columns with DataTemplate key is SetCellBoundValue. When you enable SetCellBoundValue, it sets the DataContextHelper as DataContext to CellTemplate. DataContextHelper contains the following properties,
- Value – denotes the value from data based on MappingName property.
- Record – denotes the underlying data.
Now you can make use of Value property that provides value based on MappingName property and you can use the same template for any number of Columns that binds the value based on MappingName.
The following code example illustrates on how to use the above property.
<!-- Add this code example in Resources
Define the DataTemplate with Key.-->
<DataTemplate x:Key="DefaultTemplate">
<TextBlock Text="{Binding Path=Value}" Margin="5" FontWeight="Bold" FontStyle="Italic"/>
</DataTemplate>
<!-- Define Grid Columns,
Use the key to column’s CellTemplate property via binding in a
StaticResource and enable SetCellBoundValue. -->
<syncfusion:GridTextColumn MappingName="Quantity"
TextAlignment="Center"
SetCellBoundValue="True"
CellTemplate="{StaticResource DefaultTemplate}"/>
<syncfusion:GridDateTimeColumn HeaderText="Order Date"
MappingName="Shipping"
SetCellBoundValue="True"
CellTemplate="{StaticResource DefaultTemplate}"/>
<syncfusion:GridNumericColumn HeaderText="Freight"
MappingName="Freight"
SetCellBoundValue="True"
CellTemplate="{StaticResource DefaultTemplate}" />
The above XAML code renders the following output.
CellTemplateSelector provides a way to select DataTemplate based on the data object and the data-bound element. The following code example explains you on how to use TemplateSelector.
Create required templates with static keys.
<!-- Add this code example in Resources-->
<DataTemplate x:Key="DefaultTemplate">
<TextBlock Text="{Binding Path=Value}" Foreground="Red" TextAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="AlternateTemplate">
<TextBlock Text="{Binding Path=Value}" Foreground="Green" TextAlignment="Center"/>
</DataTemplate>
Define the templates based on values to be applied in TemplateSelector. The following code example illustrate that how the different Data Templates applied to grid cells.
public class TemplateSelector : DataTemplateSelector
{
private DataTemplate _defaultTemplate;
/// <summary>
/// Gets or sets DefaultTemplate
/// </summary>
public DataTemplate DefaultTemplate
{
get { return _defaultTemplate; }
set { _defaultTemplate = value; }
}
private DataTemplate _alternateTemplate;
/// <summary>
/// Gets or Sets AlternateTemplate
/// </summary>
public DataTemplate AlternateTemplate
{
get { return _alternateTemplate; }
set { _alternateTemplate = value; }
}
private string _propertyToEvaluate;
/// <summary>
/// Gets or sets property to evaluate
/// </summary>
public string PropertyToEvaluate
{
get { return _propertyToEvaluate; }
set { _propertyToEvaluate = value; }
}
public override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
//The item that comes from CellTemplate is DataContextHelper. When set SetCellBoundValue to true, it sets DataContextHelper as DataContext to DataTemplate. Refer property section of CellTemplate
OrderInfo dataUnit = (item as DataContextHelper).Record as OrderInfo;
if (dataUnit == null) return this.DefaultTemplate;
//use reflection to retrieve property
Type type = dataUnit.GetType();
PropertyInfo property = type.GetRuntimeProperty(this.PropertyToEvaluate);
//here you can know what template is required to select according to the specified property value
if (Convert.ToInt16(property.GetValue(dataUnit, null)) < 25)
return this.AlternateTemplate;
else
return this.DefaultTemplate;
}
}
DataContextHelper is the helper class that contains Record and value property to get row data and the value that bound to respective column. The following code example explains you on how to apply CellTemplateSelector.
<!--In your column you have to defined like this -->
<syncfusion:GridTextColumn
HeaderText="UnitPrice"
SetCellBoundValue="True"
MappingName="Quantity">
<syncfusion:GridTextColumn.CellTemplateSelector>
<local:TemplateSelector DefaultTemplate="{StaticResource DefaultTemplate}"
AlternateTemplate="{StaticResource AlternateTemplate}"
PropertyToEvaluate="Quantity"/>
</syncfusion:GridTextColumn.CellTemplateSelector>
</syncfusion:GridTextColumn>
The above code renders the following output.
Limitation
-
When you load Editor directly to CellTemplate (Textbox – MS, DoubleTextBox, PercentTextBox, and CurrencyTextBox - Syncfusion) in Template Column without Edit Template the grid cell cannot change to edit mode. You can just edit a value with loaded editor.
-
GridImageColumn, GridCheckBoxColumn and GridHyperLinkColumn does not contain CellTemplate support. You can check here for more reference.
Column types
Each column has its own functionalities as the columns name implies. You can use any column based on your requirements. The following statements describes you the purpose column.
GridTextColumn | When you have string type in underlying collection you can use this column. |
GridNumericColumn | When you have double type in underlying collection you can use this column. |
GridUpDownColumn | When you want to Increase and Decrease the value, You can use this column. |
GridDateTimeColumn | When you have DateTime type in underlying collection you can use this column. |
GridComboBoxColumn | When you need a Combobox in each row, you can use this column. |
GridCheckBoxColumn | When you need a Check Box in each row, you can use this column. |
GridImageColumn | When you want to show image in each row, you can use this column. |
GridHyperlinkColumn | When you want hyperlink button in each row to navigate, you can use this column. |
GridTemplateColumn | When you want to customize your column, you can use this column. |
GridUnboundColumn | When you need an additional column that is not from underlying source, you can use this column. |
GridMultiColumnDropdownList | When you want load multi columns within a drop down you can use this column. |
GridTextColumn
GridTextColumn is derived from GridTextColumnBase that is derived from GridColumn and hence it inherits all the properties of GridColumn. GridTextColumn displays and allows editing of text data. Each of the cells in GridTextColumn displays text according to the Mapping Name it is binded.
The following provides the list of all properties that supports GridTextColumn:
- IsSpellCheckEnabled: The property that gets and sets whether the spell check is enabled or not.
The following code example creates GridTextColumn.
<syncfusion:GridTextColumn MappingName="OrderID"/>
dataGrid.Columns.Add(new GridTextColumn() { MappingName = "OrderID" });
GridNumericColumn
GridNumericColumn is derived from GridEditorColumn that is derived from GridTextColumn, inheriting its properties and has few additional properties. GridNumericColumn loads SfNumericTextBox for editing. In addition to the GridColumn’s properties, GridNumericColumn supports the following list of properties:
Property | Type | Description | Default Value |
---|---|---|---|
AllowNullInput | Boolean | Specifies whether the Editor accepts Null Value or Not. | True |
BlockCharactersOnTextInput | Boolean | Specifies whether to block character during the text input or not. | True |
FormatString | String | Specifies the Format String for the column. | Empty |
ParsingMode | Parses | Specifies how to Parse the value being edited (i.e Decimal or Double Mode). | Double |
The following code example illustrates how to use GridNumericColumn.
<syncfusion:GridNumericColumn MappingName="UnitPrice"
ParsingMode="Double"
AllowNullInput="True"
BlockCharactersOnTextInput="False"
FormatString="C"/>
SfDataGrid.Columns.Add(new GridNumericColumn() {ParsingMode=Syncfusion.UI.Xaml.Controls.Input.Parsers.Double,AllowNullInput=true, FormatString="C",BlockCharactersOnTextInput=false,MappingName="UnitPrice"});
The following screenshot illustrates the output.
FormatString:
SfDataGrid provide support for below string format in GridNumericColumn,
- C – Column formats the value in CurrencyFormat.
- N – Column formats the value in NumericFormat.
- P - Column formats the value in PercentFormat.
GridDateTimeColumn
GridDateTimeColumn derives from GridTextColumnBase that derives from GridColumn inheriting its properties and includes other properties as follows. GridDateTimeColumn uses SfDatePicker for editing. GridDateTimeColumn supports the following list of properties:
Property | Type | Description | Default Value |
---|---|---|---|
AllowInlineEditing | Boolean | Specifies the editor is editable using keyboard | False |
FormatString | String | Specifies the Format for the String. To know more about FormatString for DateTime . | Empty |
ShowDropDownButton | Boolean | Specifies whether to show DropDownButton for the control. | True |
The following code example illustrates how to use GridDateTimeColumn.
<syncfusion:GridDateTimeColumn HeaderText="Order Date"
ShowDropDownButton="True"
FormatString="d"
AllowInlineEditing="False"
MappingName="OrderDate" />
SfDataGrid.Columns.Add(new GridDateTimeColumn() {ShowDropDownButton=true,AllowInlineEditing=true,FormatString="d"});
The following screenshot illustrates the output.
GridComboBoxColumn
GridComboBoxColumn is derived from GridColumn, and hence it inherits all the properties of GridColumn. GridComboBoxColumn provides combobox for editing cell values and it displays a set of predefined values that is set to ItemSource in dropdown list.
To use GridComboBoxColumn, you can refer the following:
Property | Type | Description | Default Value |
---|---|---|---|
SelectedValuePath | String | Gets or sets the path that is used to get SelectedValue and SelectedItem. | Null |
ItemSource | IEnumerable | Gets or sets the collection used to generate content for the dropdown list in the Column. | Null |
DisplayMemberPath | String | Gets or sets a path to a value on the source object to serve as the visual representation of the object. | String.Empty |
ItemTemplate | DataTemplate | ItemTemplate is the dependency property that specifies the DataTemplate displays each item or not. | Null |
The following code example displays how to use GridComboBoxColumn.
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerID" />
<syncfusion:GridComboBoxColumn ItemsSource="{StaticResource ResourceKey=ComboItem}" MappingName="ShipCountry" />
<syncfusion:GridNumericColumn MappingName="UnitPrice" ParsingMode="Double"
/>
</syncfusion:SfDataGrid.Columns>
dataGrid.Columns.Add(new GridComboBoxColumn() { ItemsSource = viewModel.ComboItem, MappingName = "ShipCountry" });
The above XAML Code has resulted in the following output:
The following code example shows how to use ItemTemplate in GridComboBoxColumn.
<syncfusion:GridComboBoxColumn ItemsSource="{StaticResource ResourceKey=ComboItem}" MappingName="ShipCountry" >
<syncfusion:GridComboBoxColumn.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</syncfusion:GridComboBoxColumn.ItemTemplate>
</syncfusion:GridComboBoxColumn>
The above XAML code has resulted in the following output:
The event associated with this column is CurrentCellDropDownSelectionChanged Event
This event occurs whenever a selected item is changed in Drop Down column such as GridComboBoxColumn. The event handler receives two arguments namely sender that handles SfDataGrid and CurrentCellDropDownSelectionChangedEventArgs as objects.
The CurrentCellDropDownSelectionChangedEventArgs object contains the following properties:
- RowColumnIndex: Gets the value of the current RowColumnIndex.
- SelectedIndex: Gets the selected index from the Drop Down control.
- SelectedItem: Gets the selected item from the Drop Down control.
GridCheckBoxColumn
GridCheckBoxColumn is derived from GridColumn, and hence it inherits all the properties of GridColumn too. GridCheckBoxColumn does not load Display element and Edit element individually. It just loads Checkbox in that column to make value changes in it. You can change the underlying data source that toggles the values shown in checkbox.
The following provides the list of all properties that supports GridCheckBoxColumn:
Property | Type | Description | Default Value |
---|---|---|---|
IsThreeState | Boolean | Specifies whether the Checkbox supports two or three states.(Checked, Unchecked and Intermediate) | False |
HorizontalAlignment | HorizontalAlignment | Determines the HorizontalAlignment of the Checkbox in regard with the GridCell. | HorizontalAlignment.Center |
VerticalAlignment | VerticalAlignment | Determines the VerticalAlignment of the Checkbox in regard with the GridCell. | VerticalAlignment.Center |
The following code example shows how to use GridCheckBoxColumn.
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerID" />
<syncfusion:GridTextColumn MappingName="Country" />
<syncfusion:GridCheckBoxColumn MappingName="IsClosed"/>
<syncfusion:GridTextColumn MappingName="UnitPrice" />
</syncfusion:SfDataGrid.Columns>
dataGrid.Columns.Add(new GridCheckBoxColumn() { MappingName = "IsClosed" });
The above XAML Code has resulted in following Output:
NOTE
Due to its behavior (No Separate UIElements), it does not fire events of CurrentCellValidating and CurrentCellValidated, BeginEdit, EndEdit. You can access CurrentCellValueChanged Event.
GridImageColumn
GridImageColumn is derived from GridColumn, and hence it inherits all the properties of GridColumn too. GridImageColumn displays read-only images for the columns.
The following provides the list of all properties that supports GridImageColumn:
Property | Type | Description | Default Value |
---|---|---|---|
Stretch | Stretch | Determines a value that describes how an image is stretched to fill in the GridCell. | Stretch.Uniform |
StretchDirection | StretchDirection | Defines a value that indicates how the image is scaled. | StretchDirection.Both |
ImageWidth | Double | Defines the Width for the Image. | Double.PositiveInfinity |
ImageHeight | Double | Defines the Height for the Image. | Double.PositiveInfinity |
The following code example shows how to use GridImageColumn.
class StringToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string name = value as string;
return new BitmapImage(new Uri(string.Format(@"..\..\Images\{0}", name),UriKind.Relative));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
<Page.Resources>
<local:StringToImageConverter x:Key="stringToImageConverter" />
</Page.Resources>
<syncfusion:GridImageColumn MappingName="ImageLink"
HeaderText="Movie"
Stretch="UniformToFill"
ValueBinding="{Binding Path=ImageLink, Converter={StaticResource stringToImageConverter}}" />
The above XAML Code has resulted in the following output:
GridHyperlinkColumn
GridHyperlinkColumn is derived from GridColumn, inheriting its properties and its content represented by using the Hyperlink Button. The bound value is represented as a Hyperlink and automatically displayed as a link.
The following provides the list of all properties that supports GridHyperlinkColumn:
Property | Type | Description | Default Value |
---|---|---|---|
HorizontalAlignment | HorizontalAlignment | Determines the horizontal alignment for Hyperlink button in regard with the GridCell | HorizontalAlignment.Stretch |
VerticalAlignment | VerticalAlignment | Determines the vertical alignment for Hyperlink button in regard with the GridCell. | VerticalAlignment.Stretch |
The following code example illustrates how to use GridHyperlinkColumn.
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerID" />
<syncfusion:GridHyperlinkColumn MappingName="Country" />
<syncfusion:GridTextColumn MappingName="UnitPrice" />
</syncfusion:SfDataGrid.Columns>
dataGrid.Columns.Add(new GridHyperlinkColumn() { HeaderText = "Country", MappingName = "Country" });
The following screenshot illustrates the output.
GridHyperlinkColumn also hosts the CurrentCellRequestNavigate event to facilitate the navigation for the Hyperlink Column. The event raised whenever you try to navigate the Hyperlink. The event handler receives two arguments namely sender that handles SfDataGrid and CurrentCellRequestNavigateEventArgs as objects.
The CurrentCellRequestNavigateEventArgs object contains the following properties:
- RowColumnIndex: Gets the value for CurrentRowColumnIndex.
- NavigateText: Gets the bounded value from ValueMember or Mapping Name for the Hyperlink Button in the GridColumn.
- Handled: Specifies whether the navigation is controlled by the handler or column.
- RowData: Gets the data context by the click on Hyperlink button that is currently selected record.
GridUpDownColumn
GridUpDownColumn is derived from the GridColumn. It inherits the GridColumn properties and includes other properties. GridUpDownColumn uses the NumericUpDownControl to edit values.
The following properties support GridUpDownColumn,
Property | Type | Description | Default Value |
---|---|---|---|
Step | Double | Specifies the Step value for NumericUpDown value. | 1.0 |
MinValue | Double | Specifies the Minimum value for the control. | double.MinValue |
MaxValue | Double | Specifies the Maximum value for the control. | Double.MaxValue |
NumberDecimalDigits | Integer | Specifies the number of decimal places to be used in NumericValues. | NumberFormatInfo.CurrentInfo.NumberDecimalDigits |
AutoReverse | Boolean | Specifies whether the control automatically reverses the value when it reaches MinValue or MaxValue. | True |
FormatString | String | Specifies the format string of the value. | Empty. |
ParsingMode | Parsers | Specifies how to parse the value being edited (i.e. Decimal or Double Mode). | Double. |
SpinButtonsAlignment | SpinButtonsAlignment | Specifies the SpinButtonAlignment. | Right |
SmallChanges | Double | Specifies the SmallChange of the UpDownValue. | 1.0 |
LargeChange | Double | Specifies the LargeChange of the UpDownValue | 1.0 |
The following code example illustrate how to use GridUpDownColumn,
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerID" />
<syncfusion:GridTextColumn MappingName="Country" />
<syncfusion:GridUPDownColumn Step="1"
MappingName="UnitPrice"
MinValue="0"
MaxValue="500"
SpinButtonsAlignment="Left"
SmallChange="2"
/>
</syncfusion:SfDataGrid.Columns>
dataGrid.Columns.Add(new GridUpDownColumn(){Step=1,MappingName="UnitPrice",MinValue=0,MaxValue=500, SpinButtonsAlignment=Syncfusion.UI.Xaml.Controls.SpinButtonsAlignment.Left,SmallChange=2});
The following screenshot illustrates the output.
GridTemplateColumn
SfDataGrid supports vast number of cell types.When you require to extend the functionality of GridColumns with your own editor; it is achieved by creating CellTemplate and EditTemplate of GridTemplateColumn.
The following provides the list of all properties that supports GridTemplateColumn.
Property | Type | Description | Default Value |
---|---|---|---|
EditTemplate | DataTemplate | Specifies the data template of cell in edit mode. | Null |
CellTemplate | DataTemplate | Specifies the data template of cell in view mode. | Null |
CellTemplateSelector | DataTemplateSelector | Gets DataTemplateSelector and apply the template to cell in view. | Null |
EditTemplateSelector | DataTemplateSelector | Gets DataTemplateSelector and apply the template to the cell in edit mode. | Null |
NOTE
By default, Silverlight does not support TemplateSelectors hence SfDataGrid too.
The following code example shows template for GridTemplateColumn.
<syncfusion:GridTemplateColumn MappingName="UnitPrice">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock FontStyle="Italic"
FontWeight="Light"
Text="{Binding UnitPrice}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
<syncfusion:GridTemplateColumn.EditTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBox FontStyle="Italic"
FontWeight="SemiBold"
Text="{Binding UnitPrice,
Mode=TwoWay}" />
</Grid>
</DataTemplate>
</syncfusion:GridTemplateColumn.EditTemplate>
</syncfusion:GridTemplateColumn>
The above XAML code has resulted in the following output.
CellTemplateSelector and EditTemplateSelector provide a way to select DataTemplate based on the data object and the data-bound element. The following code example displays how to use TemplateSelector.
<!-- CELL TEMPLATE -->
<DataTemplate x:Key="maleCellTemplate">
<TextBlock Foreground="DeepSkyBlue" Text="{Binding EmployeeGender}" />
</DataTemplate>
<DataTemplate x:Key="femaleCellTemplate">
<TextBlock Foreground="DeepPink" Text="{Binding EmployeeGender}" />
</DataTemplate>
<!-- EDIT TEMPLATE -->
<DataTemplate x:Key="maleEditTemplate">
<TextBox Foreground="DeepSkyBlue" Text="{Binding EmployeeGender}" />
</DataTemplate>
<DataTemplate x:Key="femaleEditTemplate">
<TextBox Foreground="DeepPink" Text="{Binding EmployeeGender}" />
</DataTemplate>
// TEMPLATE SELECTOR
public class CellTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
var dataItem = item as OrderInfo;
if (dataItem.EmployeeGender == "Male")
return Application.Current.Resources["maleCellTemplate"] as DataTemplate;
else
return Application.Current.Resources["femaleCellTemplate"] as DataTemplate;
}
}
public class EditTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
var dataItem = item as OrderInfo;
if (dataItem.EmployeeGender == "Male")
return Application.Current.Resources["maleEditTemplate"] as DataTemplate;
else
return Application.Current.Resources["femaleEditTemplate"] as DataTemplate;
}
}
// APPLYING CELLTEMPLATESELECTOR AND EDITTEMPLATESELECTOR
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerName" />
<syncfusion:GridTemplateColumn MappingName="Gender"
CellTemplateSelector="{StaticResource cellTemplateSelector}"
EditTemplateSelector="{StaticResource editTemplateSelector}"
/>
<syncfusion:GridTextColumn MappingName="Country" />
<syncfusion:GridTextColumn MappingName="UnitPrice" />
</syncfusion:SfDataGrid.Columns>
The following screenshot shows the output for the above code.
GridTemplateColumn provides the list of attached properties to handle key navigation and focus for loaded controls within DataTemplate.
- FocusManagerHelper.WantsKeyInput
- FocusManagerHelper.FocusedElement
WantsKeyInput
The attached property allows the controls loaded in CellTemplate to handle key navigation within it or by Grid.
The following code example explains you about WantsKeyInput.
<syncfusion:GridTemplateColumn HeaderText="ProductName"
MappingName="ProductName"
syncfusion:FocusManagerHelper.WantsKeyInput="True">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBox x:Name="text" Text="{Binding ProductName}" />
</Grid>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>
NOTE
Enter and Tab keys are always handled by Grid only. When you set it to’ false’, you cannot navigate using keys within a loaded control.
FocusedElement
The attached property FocusedElement gives the Focus to particular element inside DataTemplate.
The following code example shows how to set the FocusedElement inside DataTemplate
<syncfusion:GridTemplateColumn HeaderText="Order ID" MappingName="OrderID">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding OrderID}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
<syncfusion:GridTemplateColumn.EditTemplate>
<DataTemplate>
<Grid>
<TextBox x:Name="textBox"
FontStyle="Italic"
FontWeight="SemiBold"
Padding="2,0"
Text="{Binding OrderID,
Mode=TwoWay}"
syncfusion:FocusManagerHelper.FocusedElement="True" />
</Grid>
</DataTemplate>
</syncfusion:GridTemplateColumn.EditTemplate>
</syncfusion:GridTemplateColumn>
The following XAML code example displays you how to set focus directly to editor.
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTemplateColumn HeaderText="Customer ID" MappingName="CustomerID">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerID}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
<syncfusion:GridTemplateColumn.EditTemplate>
<DataTemplate>
<Grid FocusManager.FocusedElement="{Binding ElementName=textBox}">
<TextBox x:Name="textBox"
FontStyle="Italic"
FontWeight="SemiBold"
Padding="2,0"
Text="{Binding CustomerID,
Mode=TwoWay}" />
</Grid>
</DataTemplate>
</syncfusion:GridTemplateColumn.EditTemplate>
</syncfusion:GridTemplateColumn>
</syncfusion:SfDataGrid.Columns>
Creating template columns based on MappingName
When using template column, you can define template for each column and set binding to the underlying data in template regardless of MappingName. In some use cases, you may need to bind template columns based on MappingName and also use same data template for all template columns.This is achieved by changing the Renderer for Template columns as displayed in the following code example.
The following code example explains you how to remove from Renderer collection in MainPage.cs
dataGrid.CellRenderers.Remove("Template");
dataGrid.CellRenderers.Add("Template", new GridCellDataTemplateRenderer());
By default Template column uses GridCellTemplateRenderer that sets Record as DataContext to CellTemplate and EditTemplate. GridCellDataTemplateRenderer is derived from GridCellTemplateRenderer that sets the DataContextHelper as DataContext to CellTemplate and EditTemplate.
DataContextHelper has the following properties,
- Value – denotes the value from data based on MappingName property
- Record – denotes the underlying data.
Now you can make use of Value property that provides value based on MappingName property. You can use the same template for any number of Columns that bind the value based on MappingName.
Then your XAML code is as follows.
<syncfusion:GridTemplateColumn HeaderText="Order ID" MappingName="OrderID">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>
Unbound Columns
SfDataGrid supports the addition of extra columns to the Data Source columns. These additional columns are called as unbound columns, as they do not belong to the Data Source. These unbound fields are used when you want to add additional or custom information to each record.
An unbound column is sorted, grouped, and filtered like other GridColumns. The value of an unbound column updates automatically, when a concerned property on the data item changes. It includes two important properties as follows; Format and Expression that are set. Unbound column also includes another property CaseSensitivity that specifies whether the given expression is case sensitive or not.
- Expression property denotes any valid Arithmetic or logical expression with columns for the UnBoundColumn to compute.
- Format property denotes an expression with a formatting string holding valid columns from the Data Source.
The supported arithmetic operations are as follows: You can use arithmetic operators within two column names such as Expression= “Quantity + UnitPrice.”
Operations | Operators |
---|---|
Add | + |
Subtract | - |
Multiply | * |
Divide | / |
Power | ^ |
Mod | % |
Greater Than | > |
Lesser Than | < |
Equal | = |
GreaterThanOrEqual | >= |
The supported logical operations are as follows. You have to use logical operation like Expression = “Quantity > UnitPrice” + (char) 135 + “Quantity! = UnitPrice” from code behind.
Operations | Operators |
---|---|
AND | (char)135 |
OR | (char)136 |
NOT | (char)137 |
NOTE
It is mandatory to specify the GridColumn.MappingName to the UnBoundColumn, but it should not match with any existing fields in the data source.
The following code example shows how to use unbound column in the SfDataGrid control.
<syncfusion:SfDataGrid AllowEditing="True"
ColumnSizer="Auto"
ItemsSource="{Binding OrderInfoCollection}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerName" />
<syncfusion:GridTextColumn MappingName="Quantity"/>
<syncfusion:GridTextColumn MappingName="UnitPrice"/>
<syncfusion:GridUnBoundColumn Expression="UnitPrice * Quantity"
MappingName="Total" />
<syncfusion:GridUnBoundColumn Format="'{UnitPrice} for {CustomerName}'"
MappingName="UnitPrice For Each"
/>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
The following screenshot shows the output.
Events
An unbound column provides the QueryUnboundColumnValue event that is raised when the GridUnboundColumn is initialized and updated. The event includes two arguments, namely sender that handles SfDataGrid and GridUnBoundColumnEventArgs as Objects.
GridUnBoundColumnEventArgs object contains the following properties:
- Column: Gets the GridColumn for the UnBoundColumn.
- Record: Gets the current record where the values are computed for the unbound cell.
- UnBoundAction: Gets the action for the event, i.e., whether the event is Querying the data or Committing the data.
- Value: Gets or sets the value for the UnBoundColumn.
GridUnBoundColumn provides a special property that bounds a value when given Expression columns names are not equal case. The following code example illustrates that.
<syncfusion:GridUnBoundColumn CaseSensitive="False"
Format="'{CustomerName}-{UnitPrice}'"
MappingName="UnitPrice For Each" />
The following screenshot displays you the output.
In above case, when you set CaseSensitive property value to ‘true’, then you can not get UnitPrice column value after that hyphen.
GridMultiColumnDropDownList
GridMultiColumnDropDownList is derived from GridColumn, inheriting its properties and has few additional properties. GridMultiColumnDropDownList loads SfMultiColumnDropDownControl for editing. In addition to the GridColumn’s properties, GridMultiColumnDropDownList supports the following list of properties:
Property Name | Type | Description | Default Value |
---|---|---|---|
DisplayMember | String | Determines the field in the data bound source, whose value is displayed in the Editor. | String.Empty |
ValueMember | String | Determines the field in the data bound source that computes the SelectedValue. | String.Empty |
ShowResizeThumb | Visibility | Specifies whether resizing thumb is visible or not. | Visibility.Visible |
PopUpHeight | Double | Defines the height of the Pop-up. | 0.0d |
PopUpWidth | Double | Defines the width of the Pop-up. | 0.0d |
ItemsSource | Object | Determines the data source ( IEnumerable ) used to generate the content for the SfDataGrid present inside the DropDownPopup. The Data Source is of any type ranging from ObservableCollection < T > to DynamicObjects. | Null |
AllowAutoComplete | Boolean | This property is Boolean properties that represent the behavior of the Editor, and specifies whether to enable or disable suggestion text for auto completion of text. | True |
AllowCasingforFilter | Boolean | Specifies whether Filtering is applied with Text case | False |
AllowSpinOnMouseWheel | Boolean | Specifies whether SpinOnMouse wheel is enabled or not. | True |
AllowIncrementalFiltering | Boolean | Specifies whether Incremental Filtering is enabled or not. | True |
AllowNullInput | Boolean | Specifies whether the editor accepts null value or not. | False |
AutoGenerateColumns | Boolean | Specifies a value whether the columns are auto generated by the SfDataGrid in the DropDownGrid, or generated based on the AutoGenerateColumnsMode. | True |
AutoGenerateColumnsMode | AutoGenerateColumnsMode | Specifies whether columns are created automatically for all the fields in the underlying Data Source. | Reset |
Columns | Columns | This is a collection of GridColumns that helps to generate columns based on the given GridColumns. | new Columns() |
GridColumnSizer | GridLengthUnitType | Specifies the ColumnSizer mode for a DropDownGrid in GridMultiColumnDropDownList column. | GridLengthUnitType.None |
IsAutoPopupSize | Boolean | Specifies a value that agrees whether the size of the Pop-up is based on the actual size of the Grid. | False |
The following code example illustrates how to use GridMultiColumnDropDownList.
<syncfusion:GridMultiColumnDropDownList AutoGenerateColumns="False"
DisplayMember="Freight"
GridColumnSizer="Auto"
IsAutoPopupSize="False"
ItemsSource="{Binding OrderList}"
MappingName="Freight "
ValueMember="OrderID ">
<syncfusion:GridMultiColumnDropDownList.Columns>
<syncfusion:Columns>
<syncfusion:GridTextColumn MappingName="Freight" />
<syncfusion:GridTextColumn MappingName="OrderID" />
</syncfusion:Columns>
</syncfusion:GridMultiColumnDropDownList.Columns>
</syncfusion:GridMultiColumnDropDownList>
The above XAML code has resulted in the following output.
The event associated with this column is CurrentCellDropDownSelectionChanged Event
This event occurs whenever a selected item is changed in DropDown column such as GridMultiColumnDropDownList. The event handler receives two arguments namely sender that handles SfDataGrid and CurrentCellDropDownSelectionChangedEventArgs as objects.
The CurrentCellDropDownSelectionChangedEventArgs object contains the following properties:
- RowColumnIndex: Gets the value of the current RowColumnIndex.
- SelectedIndex: Gets the selected index from the DropDown control.
- SelectedItem: Gets the selected item from the DropDown control.
NOTE
To reflect null value in view, the underlying type needs to be Nullable. Only then it accepts Null value.
Column Sizing
ColumnSizer property allows you to specify the column width based on the data present in the cell and available width of parent Framework. You can set the ColumnsSizer property like SfDataGrid.ColumnSizer. This section explains you different options to set width of each Column and how to customize the GridColumnSizer. Following are the lists of options available to set width of the Columns.
- Auto
- AutoWithLastColumnFill
- AutoLastColumnFill
- SizeToCells
- SizeToHeader
- Star
- None
GridLengthUnitType.Auto
In Auto type, column’s width of the SfDataGrid control is adjusted with respect to the cell and header content, that is each column’s header length and cell content length are considered.
GridLengthUnitType.AutoWithLastColumnFill
In AutoWithLastColumnFill type, the column width of the SfDataGrid control is adjusted with respect to cell and header content. Remaining width of parent Framework is set for last column.
GridLengthUnitType.AutoLastColumnFill
In AutoLastColumnFill type, the column width of the SfDataGrid control is adjusted with respect to cell and header content. For last column, Auto width is calculated. When AutoWidth is lesser than remaining width, remaining width is set for last column to fill the grid. Else, AutoWidth is set for last column.
GridLengthUnitType.SizeToCells
In SizeToCells type, the column width in the SfDataGrid control is adjusted with respect to cell content.
GridLengthUnitType.SizeToHeader
In SizeToHeader type, column’s width of the SfDataGrid control is adjusted with respect to header content.
GridLengthUnitType.Star
In Star type, the control content occupies total space in the parent, and column’s width is divided equally based on the total space. It’s not required to specify the width for every Grid Column.
GridLengthUnitType.None
No Column sizing is applied when the SfDataGrid.ColumnSizer is set to ‘None’. Columns are arranged in the default Column width.
Properties
SfDataGrid.ColumnSizer: This property applies the Column sizing for all the columns in the SfDataGrid control. By default the SfDataGrid.ColumnSizer is set to GridControlLengthUnitType.None.
The SfDataGrid control also allows you to set the column sizing for a particular column. Grid Column contains following properties for Column sizing:
- GridColumn.ColumnSizer: You can set the ColumnSizer for particular columns by using this property. When you declare the ColumnSizer property in SfDataGrid control as well as in Column, Grid resizes the column based on the ColumnSizer value in the column.
- GridColumn.MinimumWidth: Sets the Minimum Width of the column.
- GridColumn.MaximumWidth: Sets the Maximum Width of the column.
- GridColumn.Width: Sets the Width of the column.
NOTE
SfDataGrid control applies column sizing based on Width, MinimumWidth and MaximumWidth properties.
- The SfDataGrid resizes the column based on the GridColumn.ColumnSizer property instead of the SfDataGrid.ColumnSizer property when you set the GridColumn.ColumnSizer property explicitly.
- For example, when you set SfDataGrid.ColumnSizer property to ‘Auto’, and for a particular column you have set GridColumn.ColumnSizer property to ‘Star’, SfDataGrid applies ‘Star’ column sizing for that particular column and ‘Auto’ column sizing for all other columns.
- When you set both the GridColumn.ColumnSizer and GridColumn.Width properties, the SfDataGrid resizes the column based on the GridColumn.Width value.
- When you set both the GridColumn.MaximumWidth and GridColumn.Width properties, the Grid resizes the column in the following ways:
- When the GridColumn.Width value is lesser than GridColumn.MaximumWidth, SfDataGrid resizes the column to the GridColumn.Width value.
- Else, SfDataGrid resizes the column to GridColumn.MaximumWidth value.
- When you set GridColumn.MinimumWidth, GridColumn.MaximumWidth and GridColumn.Width properties, SfDataGrid resizes the column in the following ways:
- When the GridColumn.Width value is lesser than the GridColumn.MaximumWidth and greater than GridColumn.MinimumWidth, SfDataGrid resizes the column to the GridColumn.Width value.
- Else, SfDataGrid resizes the column with the maximum GridColumn.MinimumWidth and GridColumn.MaximumWidth values.
NOTE
When you resize the columns and the Columns sizer is in ‘Star’ or ‘AutoWithLastFill’ mode, it remains its behavior.
The following code example illustrates you on how to set the ColumnSizing option for SfDataGrid control.
<syncfusion:SfDataGrid x:Name="datagrid"
ColumnSizer="Star"
ItemsSource="{Binding OrdersDetails}" />
dataGrid.ColumnSizer = GridLengthUnitType.Star;
The following screenshot illustrates the output.
NOTE
When you set custom styles in the SfDataGrid control, the GridControlLengthUnitType.Star is the sizer option for your columns
Customize column sizer using GridColumnSizer
GridColumnSizer is the public class that handles the operations to set SfDataGrid column’s width based on column sizer and column width. Following are the list of properties and methods to be considered when you calculate column width.
Method | Description |
---|---|
internal protected virtual double CalculateAutoFitWidth(GridColumn column, bool isAuto = false) | Called to calculate column width based on 'Auto' column sizer |
protected virtual double CalculateCellWidth(GridColumn column, bool setWidth = true) | Called to calculate column width based on 'SizeToCells' column sizer |
protected virtual double CalculateHeaderWidth(GridColumn column, bool setWidth = true) | Called to calculate column width based on 'SizeToHeader' column sizer |
protected virtual double GetAutoWidth(GridColumn column) | Method used to get column width when column sizer is SizeToCells or Auto |
public virtual void SetAutoWidth(GridColumn column, double width) | Method used to set AutoWidth of the column when column sizer is SizeToCells or Auto |
protected virtual string GetDisplayText(GridColumn column, object record) | Called to get display value for calculating column width based on cell value |
protected virtual TextBlock GetTextBlock(GridColumn column, object record) | Called to get TextBlock to measure the text when column sizer is SizeToCells or Auto |
protected virtual Size MeasureText(Size rectangle, string displayText, GridColumn column, object record) | Called to measure text when column sizer is SizeToCells or Auto |
protected virtual void OnColumnPropertyChanged(GridColumn column, string property) | Invoked to refresh the column widths when ColumnSizer,Width, AllowSorting and other column properties changed for GridColumn |
public void Refresh() | Refreshes column widths when column sizer and grid size changed |
protected virtual void Refresh(double AvailableWidth) | Refreshes column widths when column sizer and grid size changed |
public void ResetAutoCalculation(GridColumn column) | Reset Auto width calculation for the particular column |
public void ResetAutoCalculationforAllColumns() | Reset Auto width calculation for all the columns |
protected internal void Resume() | Used to resume the column width refresh when column PropertyChanged is called |
public virtual double SetColumnWidth(GridColumn column, double Width) | Called to set the column width based on MinimumWidth and MaximumWidth |
protected virtual double SetNoneWidth(GridColumn column, double width) | Called to set column width based on None column sizer |
private void SetSizerWidth(double viewPortWidth) | Called to set column width based on Star column sizer |
protected internal void Suspend() | Used to suspend the column width refresh when column PropertyChanged is called |
NOTE
The above methods are useful when you create custom GridColumnSizer for SfDataGrid.
Property | Type | Description | Default Value |
---|---|---|---|
DataGrid | SfDataGrid | Gets the SfDataGrid instance | null |
FilterIconWidth | double | Gets or sets the FilterIconWidth | 28 |
FontFamily | FontFamily | Gets or sets the FontFamily | new FontFamily("Segoe UI") |
FontSize | double | Gets or sets the FontSize | 16 |
Margin | Thickness | Gets or sets the Margin | new Thickness(8, 0, 8, 0) |
SortIconWidth | double | Gets or sets the SortIconWidth | 25 |
TextBlock | TextBlock | Gets or sets the TextBlock to calculate cell width for the column | null |
Overriding and handling GridColumnSizer
The following code example illustrates to override methods and to handle operations in GridColumnSizer. The extended class GridColumnSizerExt is new GridColumnSizer and you can assign it to existing GridColumnSizer.
// Assigns custom GridColumnSizer to datagrid GridColumnSizer
dataGrid.GridColumnSizer = new GridColumnSizerExt(dataGrid);
…
/// <summary>
/// GridColumnSizerExt class is the custom GridColumnSizer
/// </summary>
public class dColumnSizerExt : GridColumnSizer
{
public GridColumnSizerExt(SfDataGrid grid)
: base(grid)
{
}
/// <summary>
/// Calculate Width for Column When Column Sizer is SizeToCells
/// </summary>
/// <param name="column">GridColumn</param>
/// <returns>column width</returns>
protected override double CalculateCellWidth(GridColumn column, bool setWidth = true)
{
return base.CalculateCellWidth(column, setWidth);
}
/// <summary>
/// Calculate Width for column when ColumnSizer is SizeToHeader
/// HeaderCell width is calculated based on HeaderText, sort icon and filter icon
/// </summary>
/// <param name="column">GridColumn</param>
/// <returns>column width</returns>
protected override double CalculateHeaderWidth(GridColumn column, bool setWidth = true)
{
return base.CalculateHeaderWidth(column, setWidth);
}
}
Hiding Columns
The SfDataGrid control provides support to Hide a particular Column in XAML or C# by setting the GridColumn.IsHidden property to ‘true’.
The following code example shows how to hide the Columns in XAML.
<syncfusion:SfDataGrid AutoGenerateColumns="False"
ColumnSizer="Auto"
ItemsSource="{Binding OrderInfoCollection}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn HeaderText="Order ID"
IsHidden="True"
MappingName="OrderID" />
<syncfusion:GridTextColumn HeaderText="Customer ID" MappingName="CustomerID" />
<syncfusion:GridTextColumn HeaderText="Name of Customer" MappingName="CustomerName" />
<syncfusion:GridTextColumn HeaderText="Ship Country" MappingName="ShipCountry" />
<syncfusion:GridTextColumn HeaderText="Ship City" MappingName="ShipCity" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
((GridTextColumn)dataGrid.Columns["OrderID"]).IsHidden = true;
NOTE
Hidden columns are not considered when applying column sizing.
Resizing Columns
This section explains you how to resize the Columns and how to handle event that arises when resizing columns.
Overview
SfDataGrid allows you to resize the Column at Execute time. By default, resizing the columns is disabled in SfDataGrid.
The following is the list of properties that participate in resizing columns.
- AllowResizingColumns
- AllowResizingHiddenColumns
To enable resizing you can set SfDataGrid.AllowResizingColumns property value to ‘True’. SfDataGrid also allows you to enable or disable the resizing functionality for a particular column by using the GridColumn.AllowResizing property.
When resizing functionality enabled, SfDataGrid shows a resizing cursor during hovering at the edge of the column header as shown in the following screenshot:
SfDataGrid provide supports to resize the column in touch device. When you press the column header and hold it. The popup window will be displayed with two rounded thumb to resize the column as shown in below image.
Hidden columns are resized by enabling SfDataGrid.AllowResizingHiddenColumns property.
The following screenshot displays how Hidden columns are displayed when AllowResizingHiddenColumns property is enabled.
The event that participates in resizing is ResizingColumns. Resize event support resizing action
SfDataGrid.ResizingColumns
This event occurs when the column in the SfDataGrid is about to resize or is being resized by you.
The ResizingColumns event handler receives two arguments sender that handles SfDataGrid type and ResizingColumnsEventArgs as objects.
The ResizingColumnsEventArgs object has the following properties:
- ColumnIndex : Gets or sets the column index of the resizing or resized column.
- Width : Gets or sets the width of the resizing or resized column
- Cancel : When this property is set to ‘true’, the event is canceled and the column is not resized.
The following code example illustrates how to cancel the ResizingColumn.
<syncfusion:SfDataGrid x:Name="dataGrid"
AllowEditing="{Binding ElementName=AllowEdit,
Path=IsChecked}"
AllowResizingColumns="True"
AllowResizingHiddenColumns="True"
ItemsSource="{Binding OrderList}"
LiveDataUpdateMode="AllowDataShaping"
ShowRowHeader="True">
You need to wire ResizingColumns event for SfDataGrid. You can refer the following method. From event args, you can cancel it. Now the columns are not resized. The indication of resizing is shown, but it is not resized.
dataGrid.AllowResizingColumns = true;
dataGrid.AllowResizingHiddenColumns = true;
dataGrid.ResizingColumns += dataGrid_ResizingColumns;
void dataGrid_ResizingColumns(object sender, ResizingColumnsEventArgs e)
{
e.Cancel = true;
}
NOTE
Resizing is restricted based on GridColumn.MinimumWidth and GridColumn.MaximumWidth.You can resize the columns to the Header and Cell text by double-clicking the header gridlines.
Reordering Columns
This section explains you about Reordering of Columns and how to handle event that participates in Reordering Columns.
Overview
The SfDataGrid control provides the drag-and-drop functionality to rearrange the Columns at Execute time. You can drag a particular column and drop the column where you need it. By default, the drag-and-drop functionality is disabled in the SfDataGrid control.
By using the SfDataGrid.AllowDraggingColumns property you can enable or disable the drag-and-drop functionality in the SfDataGrid. The SfDataGrid control also allows you to enable or disable the drag-and-drop functionality for a particular column by using the GridColumn.AllowDragging property.
You can drag the column using the mouse. SfDataGrid also provides extensive support for dragging columns in touch devices. When you press and hold the hand on column header, a pop-up window is displayed over the column header. You can then rearrange the Columns.
The following screenshot illustrates how to drag the column.
The event that participates in ReOrdering is QueryColumnDragging. It arises when you start dragging a column. QueryColumnDragging event handler receives two arguments sender that handles SfDataGrid and QueryColumnDraggingEventArgs as objects.
The QueryColumnDraggingEventArgs object has following properties.
- Cancel: you can stop dragging the Columns by setting ‘true’ to cancel.
- PopupPosition: You can get position of point where you drag or drop.
- From: you can get the index of column that you start dragging.
- To: you can get the index of column where you move.
- Reason: This property returns QueryColumnDraggingReason value.
QueryColumnDraggingReason has following enum values.
- DragStarting
- DragStarted
- Dragging
- Dropping
- Dropped
When you want to disable dragging for a particular column you can use this event and cancel the dragging of column.
Drag and Drop Customization
By default, Column drag-and-drop operations are handled by GridColumnDragDropController class. You can achieve drag-and-drop customization by overriding the methods in GridColumnDragDropController class.
Virtual methods in GridColumnDragDropController class:
Method | Prototype | Description |
---|---|---|
CanShowPopup | CanShowPopup(GridColumn column) | Returns whether the column shows pop-up for its header or not. |
OnColumnHiddenChanged | OnColumnHiddenChanged(GridColumn column) | Occurs when GridColumn’s Hidden property value is changed. |
OnPopupContentDropped | OnPopupContentDropped(Point point) | Occurs when the dragged popup is dropped. |
OnPopupContentPositionChanged | OnPopupContentPositionChanged(double HorizontalDelta, double VerticalDelta, Point mousePoint, Point mousePointOverGrid) | Occurs when popup position changes while dragging. |
PointToGridRegion | PointToGridRegion(Point point) | Called to find the GridRegion at a given point. |
CreatePopupContent | CreatePopupContent(GridColumn column) | Called when pop-up content is created. |
PopupContentDroppedOnGroupDropArea | PopupContentDroppedOnGroupDropArea(GridColumn column) | Called when a draggable pop-up is dropped on a GroupDropArea part |
PopupContentDroppedOnHeaderRow | PopupContentDroppedOnHeaderRow(int oldIndex, int newColumnIndex) | Called when a draggable pop-up is dropped on HeaderRow part |
PopupContentDroppedOnGrid | PopupContentDroppedOnGrid(Point point) | Called when a draggable pop-up is dropped on Grid part |
The following code example illustrates how to customize it.
this.dataGrid.GridColumnDragDropController = new CustomDragDrop(dataGrid);
public class CustomDragDrop : GridColumnDragDropController
{
public CustomDragDrop(SfDataGrid dataGrid)
: base(dataGrid)
{
}
protected override UIElement CreatePopupContent(GridColumn column)
{
return base.CreatePopupContent(column);
}
protected override void PopupContentDroppedOnGroupDropArea(GridColumn column)
{
base.PopupContentDroppedOnGroupDropArea(column);
}
protected override void OnPopupContentDropped(Windows.Foundation.Point point, Windows.Foundation.Point pointOverGrid)
{
base.OnPopupContentDropped(point, pointOverGrid);
}
protected override void OnPopupContentPositionChanged(double HorizontalDelta, double VerticalDelta, Windows.Foundation.Point mousePoint, Windows.Foundation.Point mousePointOverGrid)
{
base.OnPopupContentPositionChanged(HorizontalDelta, VerticalDelta, mousePoint, mousePointOverGrid);
}
protected override void PopupContentDroppedOnHeaderRow(int oldIndex, int newColumnIndex)
{
base.PopupContentDroppedOnHeaderRow(oldIndex, newColumnIndex);
}
}
How to remove column when dragging and leaving outside the Grid
You can achieve this using QueryColumnDragging. You need to hook this event from SfDataGrid.
The following code example explains you how to remove column when its out of the SfDataGrid.
this.dataGrid.QueryColumnDragging += dataGrid_QueryColumnDragging;
void dataGrid_QueryColumnDragging(object sender, Syncfusion.UI.Xaml.Grid.QueryColumnDraggingEventArgs e)
{
if (e.Reason == QueryColumnDraggingReason.Dropping)
{
var rect = GetControlRect(this.dataGrid);
if (!rect.Contains(e.PopupPosition))
{
var column = dataGrid.Columns[e.From];
dataGrid.Columns.Remove(column);
}
}
}
public Rect GetControlRect(FrameworkElement control)
{
Point locationFromWindow = control.TranslatePoint(new Point(0, 0), control);
Point locationFromScreen = control.PointToScreen(locationFromWindow);
return new Rect((locationFromScreen.X - locationFromWindow.X),
(locationFromScreen.Y - locationFromWindow.Y),
control.ActualWidth, control.ActualHeight);
}
Frozen Columns
The SfDataGrid control provides extensive support to freeze the columns in horizontal scrolling. To freeze the column, you have to set the number of columns by using the SfDataGrid.FrozenColumnCount property.
The following code example illustrates freezing two columns.
<syncfusion:SfDataGrid x:Name="syncgrid"
FrozenColumnCount="2"
ItemsSource="{Binding OrderInfoCollection}" />
this.dataGrid.FrozenColumnCount = 2;
The following screenshot illustrates the output.
NOTE
In the above screenshot, the OrderID and CustomerName columns are frozen. When you group the columns, indent column (while group you can see that another column is created is with grouped expander) is also frozen.
Limitation
FrozenColumnCount is lesser than view port size.
For example:
Your defined columns count is Eight.
You can set Frozen Column count as Four.
When your Page displays only 4 columns, then you cannot scroll it to view other 4 columns. So you have to set FrozenColumnCount lesser than a number of columns in view.
Stacked Headers
SfDataGrid allows you to have additional unbound header rows, known as StackedHeaderRows that span across Grid Columns. You can group two or more columns under each of the StackedHeader.
Overview
StackedHeaderRow for the given SfDataGrid is loaded under Stacked Header Rows Collection. This collection has definitions for Stacked Header Row that contains StackedColumns controlling the behavior and appearance of the StackedHeader. A StackedHeaderRow is viewed as a set of StackedColumns where each StackedColumn contains a number of Child Columns. When the Child Columns in the StackedHeader is dragged and dropped to another area of columns, the Child Column isolates itself with its own Stacked Header in the dropped position.
NOTE
Stacked Header does not participate in grouping, filtering or sorting. However, the Child Columns are allowed to group, sort or apply filter.
Stacked Column provides the following properties for implementing StackedHeaders.
- ChildColumns: Gets or sets string of Grid Columns to be grouped under the header. Commas are used as a separator for specifying list of Child Columns.
- HeaderText: Gets or sets a string for Stacked Header Text.
The following code example illustrates how to create StackedHeaders.
<syncfusion:SfDataGrid.StackedHeaderRows>
<syncfusion:StackedHeaderRow>
<syncfusion:StackedHeaderRow.StackedColumns>
<syncfusion:StackedColumn ChildColumns="OrderID" HeaderText="OrderDetails" />
<syncfusion:StackedColumn ChildColumns="CustomerName,CustomerID,Gender,Country" HeaderText="CustomerDetails" />
<syncfusion:StackedColumn ChildColumns="UnitPrice,Quantity" HeaderText="Total" />
</syncfusion:StackedHeaderRow.StackedColumns>
</syncfusion:StackedHeaderRow> </syncfusion:SfDataGrid.StackedHeaderRows>
The following screenshot displays the output for the above XAML code.
How To
How to wrap text in Column header
When you have header text that has more length then you need to set it in a multiline. You can achieve this by using HeaderTemplate in Grid Column.
The following code example illustrates this.
<syncfusion:GridTextColumn DisplayBinding="{Binding Path=OrderID}">
<syncfusion:GridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="OrderID of product has been purchased" TextWrapping="Wrap" />
</DataTemplate>
</syncfusion:GridTextColumn.HeaderTemplate>
</syncfusion:GridTextColumn>
The following screenshot illustrates the output.
NOTE
You need to set HeaderRowHeight in SfDataGrid to differentiate TextWrap in columnHeader.
SfDataGrid.HeaderRowHeight = “100”;
How to skip AutoGenerate column for particular property
When you set AutoGenerateColumns to ‘true’, columns are generated based on attributes specified in the Model. You can achieve this in following ways.
Using DisplayAttribute
[Display(AutoGenerateField= false,Description="This filed is not created")]
public int OrderID
{
get { return orderID; }
set { orderID = value; }
}
AutoGenerateField disabled in Display attribute does not create the column.
Using BindableAttribute
[Bindable(false)]
public string CustomerName
{
get { return customerName; }
set { customerName = value; }
}
The property for which you have disabled Bindable, that property is added to columns collection.
Using AutoGeneratingColumns Event.
void dataGrid_AutoGeneratingColumn(object sender, Syncfusion.UI.Xaml.Grid.AutoGeneratingColumnArgs e)
{
if (e.Column.MappingName == "Country")
e.Cancel = true;
}
How to override existing Cell types?
In SfDataGrid each column has associated cell types that are added in CellRenderers collection. You can remove and add it back by your customized renderer. The following code example explains you how to override existing Cell types.
public class GridCellTextBoxRendererExt: GridCellTextBoxRenderer
{
protected override bool ShouldGridTryToHandleKeyDown(KeyEventArgs e)
{
// TODO ACTION
}
}
You can derive the required renderer and you can customize using override methods available in it.
public MainPage()
{
InitializeComponent();
dataGrid.CellRenderers.Remove("TextBox");
dataGrid.CellRenderers.Add("TextBox", new GridCellTextBoxRenderer());
}
The key argument that is used to remove is CellType. You can add it back by using the name of CellType with your Customized renderer (GridCellTextBoxRendererExt) name. You can do this for different Cell types. Available Cell types for Columns in SfDataGrid are as follows.
Column | Cell Type | Renderer |
---|---|---|
GridTextColumn | TextBox | GridCellTextBoxRenderer |
GridCheckBoxColumn | CheckBox | GridCellCheckBoxRenderer |
GridTemplateColumn | Template | GridCellTemplateRenderer |
GridImageColumn | Image | GridCellImageRenderer |
GridUnBoundColumn | UnBoundTemplateColumn | GridUnBoundCellTemplateRenderer |
GridUnBoundColumn | UnBoundTextColumn | GridUnBoundCellTextBoxRenderer |
GridNumericColumn | Numeric | GridCellNumericRenderer |
GridDateTimeColumn | DateTime | GridCellDateTimeRenderer |
GridHyperlinkColumn | Hyperlink | GridCellHyperLinkRenderer |
How to enable Tooltips for Cell and Headers?
SfDataGrid provides support to apply Tooltip for Cell and Headers. You can achieve this by using the properties ToolTipTemplate for Cells and HeaderToolTipTemplate for HeaderCells in GridColumn. The following code example illustrates this.
<syncfusion:GridTextColumn DisplayBinding="{Binding Path=CustomerID}" MappingName="CustomerID">
<syncfusion:GridTextColumn.ToolTipTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerID}" />
</DataTemplate>
</syncfusion:GridTextColumn.ToolTipTemplate>
<syncfusion:GridTextColumn.HeaderToolTipTemplate>
<DataTemplate>
<TextBlock Text="Hedaer for CutomerID" />
</DataTemplate>
</syncfusion:GridTextColumn.HeaderToolTipTemplate>
</syncfusion:GridTextColumn>
The following screenshot displays the output of Tooltip applied in Header cell.
The following screenshot displays the output of Tooltip applied in Cells.
How to disable drag and drop between Frozen columns and Non-Frozen columns
You can wire QueryColumnDragging event for SfDataGrid. Its arguments have reason property that helps you to perform any actions while dragging and dropping. It has From and To property that shows you where the dragging column is present.
SfDataGrid has FrozenColumnCount property that gives you number of frozen column that you have set.
ResolveToStartColumnIndex () is the method that returns the index of first column, since the start column index is not always first column index. When you group or set ShowRowHeader for SfDataGrid or define Master-Details View, column index gets varied. So, the method is used to calculate frozen column index at that time.
this.datagrid.QueryColumnDragging += datagrid_QueryColumnDragging;
void datagrid_QueryColumnDragging(object sender, Syncfusion.UI.Xaml.Grid.QueryColumnDraggingEventArgs e)
{
if (e.Reason == QueryColumnDraggingReason.Dropping)
{
var frozenColumnIndex = datagrid.FrozenColumnCount + this.datagrid.ResolveToStartColumnIndex();
if (e.From < frozenColumnIndex && e.To > frozenColumnIndex - 1)
e.Cancel = true;
if (e.From > frozenColumnIndex && e.To < frozenColumnIndex || (e.From == frozenColumnIndex && e.To < frozenColumnIndex))
e.Cancel = true;
}
}
How to bind Column properties from ViewModel
- Create New Project in Visual Studio.
- Create ItemsSource as mentioned in GettingStarted and populate items.
- In your View model, you can have property that you want bind to column.
private bool allowFiltering = true;
public bool AllowFiltering
{
get { return allowFiltering;}
set { allowFiltering = value; }
}
4.You can bind collection to ItemsSource property in SfDataGrid. The following code example illustrates how to add it to resource and how to bind it to ItemsSource.
5.The highlighted lines creates key for binding collection to SfDataGrid.
<Page x:Class="SimpleApplication.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SimpleApplication"
xmlns:syncfusion="using:Syncfusion.UI.Xaml.Grid"
Title="MainWindow"
Width="525"
Height="350">
<Page.DataContext>
<local:OrderInfoRepository />
</Page.DataContext>
<Page.Resources>
<local:OrderInfoRepository x:Key="data" />
</Page.Resources>
<Grid>
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumns="False"
ColumnSizer="Star"
ItemsSource="{Binding OrderInfoCollection,
Source={StaticResource data}}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn AllowFiltering="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MainWindow}}, Path=DataContext.AllowFiltering}" MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerID" />
<syncfusion:GridTextColumn AllowFiltering="{Binding AllowFiltering, Source={StaticResource data}}" MappingName="CustomerName" />
<syncfusion:GridTextColumn MappingName="ShipCity" />
<syncfusion:GridTextColumn MappingName="Country" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
</Grid>
</Page>
To use RelativeSource way to bind, you can set DataContext. OrderID column AllowFiltering property value is binded using relative source. CustomerName column gets AllowFiltering value from StaticResource.
How to bind ComboBoxColumn ItemsSource from ViewModel
-
Create New Project in VisualStudio.
-
Create ItemsSource as explained in GettingStarted.
-
Now create ItemsSource for ComboBoxColumn in ViewModel.
-
You can have list of strings as items source to ComboBoxColumn.
-
First highlighted box indicates your ComboBoxColumnItemsSource declaration. Second highlighted box populates items for list.
public class ViewModel
{
ObservableCollection<OrderInfo> orderCollection;
private List<string> comboItems = new List<string>();
public List<string> ComboItems
{
get { return comboItems; }
set { comboItems = value; }
}
public ObservableCollection<OrderInfo> OrderInfoCollection
{
get { return orderCollection; }
set { orderCollection = value; }
}
public ViewModel()
{
orderCollection = new ObservableCollection<OrderInfo>();
this.GenerateOrders();
foreach(OrderInfo o in orderCollection)
{
ComboItems.Add(o.CustomerName);
}
}
private void GenerateOrders()
{
orderCollection.Add(new OrderInfo(1001, "Maria Anders", "Germany", "ALFKI", "Berlin"));
orderCollection.Add(new OrderInfo(1002, "Ana Trujillo", "Mexico", "ANATR", "Mexico D.F."));
orderCollection.Add(new OrderInfo(1003, "Antonio Moreno", "Mexico", "ANTON", "Mexico D.F."));
orderCollection.Add(new OrderInfo(1004, "Thomas Hardy", "UK", "AROUT", "London"));
orderCollection.Add(new OrderInfo(1005, "Christina Berglund", "Sweden", "BERGS", "Lula"));
orderCollection.Add(new OrderInfo(1006, "Hanna Moos", "Germany", "BLAUS", "Mannheim"));
orderCollection.Add(new OrderInfo(1007, "Frederique Cite", "France", "BLONP", "Strasbourg"));
orderCollection.Add(new OrderInfo(1008, "Martin", "Spain", "BOLID", "Madrid"));
orderCollection.Add(new OrderInfo(1009, "Laurence", "France", "BONAP", "Marseille"));
orderCollection.Add(new OrderInfo(1010, "Elizabeth Lincoln", "Canada", "BOTTM", "Tsawassen"));
}
}
The following code example shows you how to Bind ComboItems to ComboBoxColumn.
<Page x:Class="SimpleApplication.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SimpleApplication"
xmlns:syncfusion="using:Syncfusion.UI.Xaml.Grid"
Title="MainWindow"
Width="525"
Height="350">
<Page.Resources>
<local:ViewModel x:Key="data" />
</Page.Resources>
<syncfusion:SfDataGrid x:Name="dataGrid"
AllowEditing="True"
AutoGenerateColumns="False"
ColumnSizer="Star"
ItemsSource="{Binding OrderInfoCollection,
Source={StaticResource data}}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridComboBoxColumn ItemsSource="{Binding Path=ComboItems, Source={StaticResource data}}" MappingName="CustomerName" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
</Page>
The following screenshot displays the output
How to style Hyperlink Column
SfDataGrid has Hyperlink Column that directly loads Hyperlink control as its UIElement. You can directly set style for Hyperlink control with its TargetType as Hyperlink. Then the style is applied to GridHyperlinkColumn. The following code example illustrates how to set style HyperlinkColumn.
<Page x:Class="SimpleApplication.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SimpleApplication"
xmlns:syncfusion="using:Syncfusion.UI.Xaml.Grid"
Title="MainWindow"
Width="525"
Height="350">
<Page.DataContext>
<local:ViewModel />
</Page.DataContext>
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding OrderInfoCollection}" >
<syncfusion:SfDataGrid.Resources>
<Style TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="Red" />
</Style>
</syncfusion:SfDataGrid.Resources>
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn MappingName="OrderID" />
<syncfusion:GridTextColumn MappingName="CustomerName" />
<syncfusion:GridHyperlinkColumn MappingName="ShipCity" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
</Page>
The following screenshot displays the output.
Difference between DisplayBinding , ValueBinding and MappingName properties
DisplayBinding
Denotes the binding to DataModel while loading (In Non-Edit mode).
ValueBinding
Denotes the binding to DataModel for Edit element.
MappingName
MappingName property denotes the property present in underlying DataModel that needs to bound to the Column. When setting MappingName, then DisplayBinding and ValueBinding are created to the underlying DataModel based on MappingName.
By default, data manipulation operations like Sorting, Grouping, Filtering,etc are based on MappingName and the values are reflected using reflection from DataModel. Setting UseBindingValue property to ‘true’, enables the advanced features like sorting, grouping, filtering, etc that reflects the values based on ValueBinding that enables you to bind more complex binding paths.
NOTE
Set UseBindingValue only when you are binding more complex property paths or when standard reflection can’t reflect the data from Data model.
Define Hyperlink Column that redirects to an URI whose values are not bound to a Column
When URI or URL is very long, and you can find it hard to bind the URL to the GridHyperlinkColumn, or you may want to hide the RequestURI from the View. In both cases, you can implement any of the following two approaches to define the GridHyperlinkColumn.
Method 1
DisplayBinding and ValueBinding in GridColumns of SfDataGrid are used in this case. You can set the DisplayBinding to the value you want to display in view, and bind the ValueBinding to the URI where you want the control to navigate.
The following code example illustrates this.
<syncfusion:GridHyperlinkColumn DisplayBinding="{Binding Path=ProductName}"
HeaderText="Official Product Link"
MappingName="ProductName"
ValueBinding="{Binding Path=ProductURI}" />
Method 2
Hyperlink Column provides the CellRequestNavigate event that is raised whenever you try to navigate using the Hyperlink control in GridHyperlinkColumn. This event is used to set the sender’s (Hyperlink Button) NavigateURI dynamically at Execute time.
The following code example illustrates how to handle the CellRequestNavigate event and URI dynamically.
void sfDataGrid_CurrentCellRequestNavigate(object sender, CurrentCellRequestNavigateEventArgs args)
{
var hyperlinkControl=(sender as Hyperlink);
var URI = string.Format("http://www." + args.NavigateText + ".com");
hyperlinkControl.NavigateUri = new Uri(URI);
args.Handled = true;
}
The following screenshot illustrates the output.
How to change FilterIconWidth and SortIconWidth when you calculate column width based on SizeToHeader column sizer
By default, column width is calculated based on the fixed FontSize, FilterIconWidth,and SortIconWidth. When you change FilterIconWidth and Sort icon width, it does not consider the changed width while calculating column width. Therefore, column width is not fit based on SizeToHeader column sizer. You can use the following code example to calculate the column width based on the new FilterIconWidth and SortIconWidth values.
dataGrid.GridColumnSizer.FilterIconWidth = 20;
dataGrid.GridColumnSizer.SortIconWidth = 20;
How to customize star width calculation
When column sizer is Star, the control content occupies total space in the parent, and column’s width is divided equally based on the total space by default. When you want to customize the star width calculation as in grid panel, you can use custom GridColumnSizer.
Consider, the grid contains four columns and you can set the width as 1,2,3,1 respectively.
The following code example illustrates how to customize star width calculation.
<syncfusion:SfDataGrid x:Name="sfGrid"
Grid.Row="1"
AutoGenerateColumns="False"
ColumnSizer="Star"
ItemsSource="{Binding OrdersListDetails}"
ShowRowHeader="False">
<syncfusion:SfDataGrid.Columns>
<syncfusion:GridTextColumn HeaderText="Order ID" MappingName="OrderID" />
<syncfusion:GridTextColumn HeaderText="Employee ID"
MappingName="EmployeeID"
TextAlignment="Center" />
<syncfusion:GridTextColumn MappingName="Quantity" />
<syncfusion:GridDateTimeColumn HeaderText="Order Date" MappingName="Shipping" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
// Assign custom GridColumnSizer to datagrid GridColumnSizer
dataGrid.GridColumnSizer = new ColumnSizerExt(dataGrid);
public class ColumnSizerExt : GridColumnSizer
{
public ColumnSizerExt(SfDataGrid grid)
: base(grid)
{
}
protected override void SetStarWidth(double remainingColumnWidth, IEnumerable<GridColumn> remainingColumns)
{
var starValues=new Dictionary<string,int>();
starValues.Add("OrderID",1);
starValues.Add("EmployeeID",2);
starValues.Add("Quantity",3);
starValues.Add("Shipping",1);
var removedColumn = new List<GridColumn>();
var columns = remainingColumns.ToList();
var totalRemainingStarValue = remainingColumnWidth;
double removedWidth = 0;
bool isRemoved;
while (columns.Count > 0)
{
isRemoved = false;
removedWidth = 0;
var columnsCount = 0;
columns.ForEach((col)=>
{
columnsCount += starValues[col.MappingName];
});
double starWidth = Math.Floor((totalRemainingStarValue / columnsCount));
var column = columns.First();
starWidth *= starValues[column.MappingName];
double computedWidth = SetColumnWidth(column, starWidth);
if (starWidth != computedWidth && starWidth > 0)
{
isRemoved = true;
columns.Remove(column);
foreach (var remColumn in removedColumn)
{
if (!columns.Contains(remColumn))
{
removedWidth += remColumn.ActualWidth;
columns.Add(remColumn);
}
}
removedColumn.Clear();
totalRemainingStarValue += removedWidth;
}
totalRemainingStarValue = totalRemainingStarValue - computedWidth;
if (!isRemoved)
{
columns.Remove(column);
if (!removedColumn.Contains(column))
removedColumn.Add(column);
}
}
}
}
The following screenshot illustrates the output image after applying star column sizer. The column widths are calculated based on 1, 2, 3* and 1*.
How to apply column sizer after resizing the columns
When you resize the particular column, the width is set for that column. After resizing the column, when you apply column sizer, column width is not set based on column sizer. It maintains the previous width only. You can overcome this scenario by resetting the width of the columns before changing the ColumnSizer as illustrated in the following code example.
foreach (var column in dataGrid.Columns)
{
if(!double.IsNaN(column.Width))
column.Width = double.NaN;
}
dataGrid.ColumnSizer = GridLengthUnitType.SizeToCells;
How to customize column width calculation for particular column
By default, column width is calculated based on the fixed FontSize, FontFamily and Margin. When any column is customized with different FontSize and FontFamily, it does not consider while calculating column width. Therefore, the column width is not fit based on the header and cell value even though column sizer is Auto. You can overcome this scenario by overriding GetTextBlock method in GridColumnSizer as illustrated in the following code example.
// Assign custom GridColumnSizer to datagrid GridColumnSizer
grid.GridColumnSizer = new CustomColumnSizer(grid);
public class CustomColumnSizer : GridColumnSizer
{
public CustomColumnSizer(SfDataGrid dataGrid)
: base(dataGrid)
{
}
protected override TextBlock GetTextBlock(GridColumn column, object record)
{
if (TextBlock == null)
TextBlock = new TextBlock();
if (column.MappingName == "Name")
{
TextBlock.FontFamily = new System.Windows.Media.FontFamily("TimesNewRoman");
TextBlock.Margin = new Thickness(50, 1, 0, 0);
TextBlock.FontSize = 20;
}
else
{
TextBlock.FontFamily = FontFamily;
TextBlock.Margin = Margin;
TextBlock.FontSize = FontSize;
}
return TextBlock;
}
}
How to change column width based on the cell value at run time
When SfDataGrid column sizer is SizeToCells, the column width is adjusted with respect to cell content.
After editing the cell value, column width is not adjusted based on new cell value instead it maintains previous width only. You can overcome this by refreshing grid column width using the following code example.
this.dataGrid.Loaded += dataGrid_Loaded;
void dataGrid_Loaded(object sender, RoutedEventArgs e)
{
dataGrid.View.RecordPropertyChanged += View_RecordPropertyChanged;
}
void View_RecordPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var column = dataGrid.Columns.FirstOrDefault(c => c.MappingName == e.PropertyName);
dataGrid.GridColumnSizer.ResetAutoCalculation(column);
dataGrid.GridColumnSizer.Refresh();
}
How to create custom column?
CustomColumn support
SfDataGrid allows you to create your own column other than SfDataGrid predefined column collection. You can decide column’s keyboard interaction, the events you want to hook and validation from renderer creation. This section explains you on how to create custom column. Custom column can be created by overriding predefined renderers with renderer replacement or can be adding new custom renderer to renderer collection. There are two steps to create custom column.
- Creating custom Renderer for column
- Creating custom column
Creating custom Renderer for column
You can create custom renderer by deriving from GridVirtualizingCellRenderer<D, E>. It contains generic parameters Where ‘D’ denotes the type display control and ‘E’ denotes the type of edit control. You can load your custom control as display or edit control or you can also load standard controls (TextBlock, Text Box, Combo Box…) and you can customize it in your way. You can also override the existing renderers and you can create customized one. There are some list of existing renderers available in SfDataGrid.
The following code example illustrates on how to create custom renderer to load SfTimePicker as Edit element and TextBlock as display element.
/// <summary>
/// CustomRenderer Creation
/// </summary>
/// <param name="TextBlock">Display Control</param>
/// <param name="SfTimePicker">Edit Control</param>
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
// TextBlock is set as Display control.
// SfTimePicker is set as Edit control.
}
The following table lists the virtual methods and properties available in GridVirtualizingCellRenderer that helps you to create your custom renderer.
Property | Type | Description | Default Value |
---|---|---|---|
IsEditable | Bool | The property that specify, the column can be editable. If you set false the column cannot edit.E.g.: Hyperlink, Image and Checkbox columns are not editable. | True |
CurrentCellIndex | RowColumnIndex | The property that returns row and column index of current cell | Null |
CurrentCellElement | FrameworkElement | Returns the GridCell which hold the Edit/Display element of the CurrentCell. | Null |
CurrentCellRendererElement | FrameworkElement | Return the Display/Edit element of the CurrentCell Renderer. | Null |
IsInEditing | bool | The property that gets or sets whether the current cell is edit mode or not. If you set false when you edit, Edit element will not unload. | False |
HasCurrentCellState | bool | Gets that cell state for the current cell has been set. | False |
SupportsRenderOptimization | bool | The property that gets or sets that display and edit can be different controls. | True |
Method | Description |
---|---|
protected virtual D OnCreateDisplayUIElement() | Create the Element of type D specified with the GridVirtualizingCellRenderer. Which creates the default display element for renderer and returns. |
protected virtual E OnCreateEditUIElement() | Creates a new Edit UIElement of type E specified with the GridVirtualizingCellRenderer type parameter. Which creates the default edit element for renderer and returns |
public abstract void OnInitializeDisplayElement(DataColumnBase dataColumn, D uiElement, object dataContext); | Creates binding between GridColumn properties, Display element properties and also initialize default settings for Display element. You can do, your own binding settings with skipping base.OnInitializeDisplayElement being called. |
public abstract void OnInitializeEditElement(DataColumnBase dataColumn, E uiElement,object dataContext); | Creates binding between GridColumn properties, Edit element properties and also initialize default settings for Edit element. You can do, your own binding settings with skipping base. OnInitializeEditElement being called. |
public abstract void OnUpdateDisplayBinding(DataColumnBase dataColumn, D uiElement, object dataContext) | Updates the binding for display element when scrolling and Data Management operations like grouping, Sorting, Filtering. This method will internally call OnInitializeDisplayElement. |
public abstract void OnUpdateEditBinding(DataColumnBase dataColumn, E element,object dataContext); | Updates only DataContext for Edit element. Which calls OnInitializeEditElement. For SupportRenderOptimization was set to false. |
protected virtual void OnEditElementLoaded(object sender, RoutedEventArgs e) | When edit element was ready for interaction OnEditElementLoaded method will be called. You can set focus for edit element (sender) and can give selection behavior for the text in edit element. |
protected virtual void OnEnteredEditMode(DataColumnBase dataColumn, FrameworkElement currentRendererElement) | When you start edit mode. You can update the current cell state of editing with IsInEditing is update to true. If you set false, then the RowHeaderState changes, Cell or Row Validation, Setting Edit item will not happen. |
protected virtual void OnEditingComplete(DataColumnBase dataColumn, FrameworkElement currentRendererElement) | When you complete editing with the cell (When do, enter/Tab/Right/Left/Home/Page Up/page Down/Up/Down key navigation) you will get an edit control with edited value. |
protected virtual bool ShouldGridTryToHandleKeyDown(KeyEventArgs e) | Key Interaction on column will be done in this method. You can decide that the selected cell can allow to navigate with the pressed key. If it return false, pressed key must be handled by GridCell else it leaves to handle by SfDataGrid. |
public virtual object GetControlValue() | Returns the display or edit control value for validation purpose. |
public virtual void SetControlValue(object value) | The method that set value to display or edit controls. |
public virtual void UpdateSource(FrameworkElement cellElement) | Method that updates the source by BindingExpression |
public virtual bool CanUpdateBinding(GridColumn column) | Decides Whether to refresh the bindings of Element whenever the DataContext gets changed. By default it return false. If you need to use different binding in one column then return as false |
public virtual bool CanValidate() | Decides whether to do cell validation for GridCell. By default it returns true. (where you want the cell should always focused if it has invalid data) |
You can define the default behavior by the properties with constructor of derived class.
//Renderer Creation.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
//Constructor of class
public TimePickerRenderer()
{
}
}
The following code example illustrates you on how to create display and edit element in custom renderer.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
/// <summary>
/// Create new display element.
/// </summary>
/// <returns></returns>
protected override TextBlock OnCreateDisplayUIElement()
{
return new TextBlock();
}
/// <summary>
/// Create new edit element.
/// </summary>
/// <returns></returns>
protected override SfTimePicker OnCreateEditUIElement()
{
return new SfTimePicker();
}
}
The following code example explains you how to initialize properties binding for display element and update bindings.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
/// <summary>
/// Initialize display element with binding.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnInitializeDisplayElement(DataColumnBase dataColumn, TextBlock uiElement, object dataContext)
{
SetDisplayBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Update display elements binding while scrolling.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnUpdateDisplayBinding(DataColumnBase dataColumn, TextBlock uiElement, object dataContext)
{
SetDisplayBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// custom binding for display element.
/// </summary>
/// <param name="element"></param>
/// <param name="column"></param>
/// <param name="dataContext"></param>
private static void SetDisplayBinding(TextBlock element, GridColumn column, object dataContext)
{
var customColumn = (TimePickerColumn)column;
var binding = new Binding
{
Path = new PropertyPath(customColumn.MappingName),
Mode = BindingMode.TwoWay,
Converter = column.DisplayBinding.Converter, //Bind Custom converter for display.
};
element.SetBinding(TextBlock.TextProperty, binding);
}
}
The following code example explains you on how to initialize properties binding for edit element and update bindings.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
/// <summary>
/// Initialize edit element with binding
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnInitializeEditElement(DataColumnBase dataColumn, SfTimePicker uiElement, object dataContext)
{
SetEditBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Update binding for edit element while scrolling.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="element"></param>
/// <param name="dataContext"></param>
public override void OnUpdateEditBinding(DataColumnBase dataColumn, SfTimePicker element, object dataContext)
{
SetEditBinding(element, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Update binding for edit element while scrolling.
/// </summary>
/// <param name="cellRowColumnIndex"></param>
/// <param name="element"></param>
/// <param name="column"></param>
/// <param name="dataContext"></param>
public override void OnUpdateEditBinding(RowColumnIndex cellRowColumnIndex, SfTimePicker element, GridColumn column, object dataContext)
{
SetEditBinding(element, column, dataContext);
}
/// <summary>
/// Custom binding for edit element.
/// </summary>
/// <param name="element"></param>
/// <param name="column"></param>
/// <param name="dataContext"></param>
private static void SetEditBinding(SfTimePicker element, GridColumn column, object dataContext)
{
var customColumn = (TimePickerColumn)column;
var binding = new Binding
{
Path = new PropertyPath(customColumn.MappingName),
Mode = BindingMode.TwoWay,
};
element.SetBinding(SfTimePicker.ValueProperty, binding);
}
}
The following code example illustrates that how can you make use of OnEditElementLoaded method.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
/// <summary>
/// When edit element ready for interaction this method is called.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnEditElementLoaded(object sender, RoutedEventArgs e)
{
var timePicker = (sender as SfTimePicker);
timePicker.Focus(FocusState.Programmatic);
}
}
The following code example illustrates you on how the key board interaction can be customized with your custom renderer.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
/// <summary>
/// Let Renderer decide whether the parent grid should be allowed to handle keys and prevent
/// the key event from being handled by the visual UIElement for this renderer. When this method
/// returns true the parent grid handles arrow keys and set the Handled flag in the event
/// data. Keys that the grid does not handle is ignored and is routed to the UIElement
/// for this renderer.
/// </summary>
/// <param name="e">A <see cref="KeyEventArgs" /> object.</param>
/// <returns>
/// True when the parent grid should be allowed to handle keys; false otherwise.
/// </returns>
protected override bool ShouldGridTryToHandleKeyDown(Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
if (!HasCurrentCellState)
return true;
if (!IsInEditing)
{
if (!(CurrentCellRendererElement is SfTimePicker))
return true;
}
return base.ShouldGridTryToHandleKeyDown(e);
}
}
The following code examples illustrates the custom renderer with converter.
//Custom Converter Here
class ConvertToDateTimeClass
{
public string ConvertToDateTime(object value)
{
DateTime date = Convert.ToDateTime(value);
return date.Day + "/" + date.Month + "/" + date.Year;
}
}
internal class CustomConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (string.IsNullOrEmpty(value.ToString()))
return null;
return new ConvertToDateTimeClass().ConvertToDateTime(value);
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return new ConvertToDateTimeClass().ConvertToDateTime(value);
}
}
//Renderer Creation.
class TimePickerRenderer : GridVirtualizingCellRenderer<TextBlock, SfTimePicker>
{
public TimePickerRenderer()
{
}
/// <summary>
/// Create new display element.
/// </summary>
/// <returns></returns>
protected override TextBlock OnCreateDisplayUIElement()
{
return new TextBlock();
}
/// <summary>
/// Create new edit element.
/// </summary>
/// <returns></returns>
protected override SfTimePicker OnCreateEditUIElement()
{
return new SfTimePicker ();
}
#region Display/Edit Value Overrides
/// <summary>
/// Gets the control value.
/// </summary>
/// <returns></returns>
public override object GetControlValue()
{
if (!HasCurrentCellState)
return base.GetControlValue();
return CurrentCellRendererElement.GetValue(IsInEditing ? SfTimePicker.ValueProperty : TextBlock.TextProperty);
}
/// <summary>
/// Sets the control value.
/// </summary>
/// <param name="value">The value.</param>
public override void SetControlValue(object value)
{
if (!HasCurrentCellState)
return;
if (IsInEditing)
((SfTimePicker)CurrentCellRendererElement).Value = value.ToString();
else
throw new Exception("Value cannot be Set for Unloaded Editor");
}
#endregion
/// <summary>
/// Initialize display element with binding.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnInitializeDisplayElement(DataColumnBase dataColumn, TextBlock uiElement, object dataContext)
{
SetDisplayBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Update display elements binding while scrolling.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnUpdateDisplayBinding(DataColumnBase dataColumn, TextBlock uiElement, object dataContext)
{
SetDisplayBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// custom binding for display element.
/// </summary>
/// <param name="element"></param>
/// <param name="column"></param>
/// <param name="dataContext"></param>
private static void SetDisplayBinding(TextBlock element, GridColumn column, object dataContext)
{
var customColumn = (TimePickerColumn)column;
var binding = new Binding
{
Path = new PropertyPath(customColumn.MappingName),
Mode = BindingMode.TwoWay,
Converter = column.DisplayBinding.Converter, //Bind Custom converter for display.
};
element.SetBinding(TextBlock.TextProperty, binding);
}
#region Edit Element
/// <summary>
/// Initialize edit element with binding
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="uiElement"></param>
/// <param name="dataContext"></param>
public override void OnInitializeEditElement(DataColumnBase dataColumn, SfTimePicker uiElement, object dataContext)
{
SetEditBinding(uiElement, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Update binding for edit element while scrolling.
/// </summary>
/// <param name="dataColumn"></param>
/// <param name="element"></param>
/// <param name="dataContext"></param>
public override void OnUpdateEditBinding(DataColumnBase dataColumn, SfTimePicker element, object dataContext)
{
SetEditBinding(element, dataColumn.GridColumn, dataContext);
}
/// <summary>
/// Custom binding for edit element.
/// </summary>
/// <param name="element"></param>
/// <param name="column"></param>
/// <param name="dataContext"></param>
private static void SetEditBinding(SfTimePicker element, GridColumn column, object dataContext)
{
var customColumn = (TimePickerColumn)column;
var binding = new Binding
{
Path = new PropertyPath(customColumn.MappingName),
Mode = BindingMode.TwoWay,
};
element.SetBinding(SfTimePicker.ValueProperty, binding);
}
/// <summary>
/// Let Renderer decide whether the parent grid should be allowed to handle keys and prevent
/// the key event from being handled by the visual UIElement for this renderer. When this method
/// returns true the parent grid handles arrow keys and set the Handled flag in the event
/// data. Keys that the grid does not handle is ignored and is routed to the UIElement
/// for this renderer.
/// </summary>
/// <param name="e">A <see cref="KeyEventArgs" /> object.</param>
/// <returns>
/// True if the parent grid should be allowed to handle keys; false otherwise.
/// </returns>
protected override bool ShouldGridTryToHandleKeyDown(Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
if (!HasCurrentCellState)
return true;
if (!IsInEditing)
{
if (!(CurrentCellRendererElement is SfTimePicker))
return true;
}
return base.ShouldGridTryToHandleKeyDown(e);
}
/// <summary>
/// When edit element ready for interaction this method will be called.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnEditElementLoaded(object sender, RoutedEventArgs e)
{
var timePicker = (sender as SfTimePicker);
timePicker.Focus(FocusState.Programmatic);
}
#endregion
}
Add your custom renderer to SfDataGrid renderer collection as in the following code example.
//Add renderer to CellRenderer Collection.
_dataGrid.CellRenderers.Add("TimePickerRenderer", new TimePickerRenderer());
Column Creation
Create a class that derives from GridColumn. Set cell type for a custom column in derived class constructor.
The following code example explains you on how to create Custom Column.
//Column Creation
public class TimePickerColumn : GridColumn
{
public TimePickerColumn()
{
SetCellType("TimePickerRenderer");
}
}
Finally, add your custom column to SfDataGrid with the following code example in XAML.
//Converter for custom column display binding.
<Grid.Resources>
<local:CustomConverter x:Key="converter"/>
</Grid.Resources>
<Syncfusion:SfDataGrid.Columns>
<local:TimePickerColumn MappingName="Shipping"
DisplayBinding="{Binding Shipping, Converter={StaticResource converter}}"
AllowEditing="True" />
</Syncfusion:SfDataGrid.Columns>
The following screenshot displays the output.