For any of these columns to be useful you are going to first need a DataGrid to add them to. The following creates a DataGrid, adds it as a child of the root layout Grid, and sets its ItemsSource to a collection called "source".
C#
DataGrid targetDataGrid = new DataGrid(); targetDataGrid.ItemsSource = source; targetDataGrid.AutoGenerateColumns = false; LayoutRoot.Children.Add(targetDataGrid);
Defining a DataGrid Text Column
The following creates a DataGridTextColumn bound to the FirstName property with a header of "First Name", and adds it to the columns collection of the DataGrid named "targetDataGrid".
<data:DataGrid x:Name="targetDataGrid"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" /> </data:DataGrid.Columns> </data:DataGrid>
C#
using System.Windows.Data;
...
DataGridTextColumn textColumn = new DataGridTextColumn(); textColumn.Header = "First Name"; textColumn.Binding = new Binding("FirstName"); targetDataGrid.Columns.Add(textColumn);
The following creates a DataGridCheckColumn bound to the Available property with a header of "Available", and adds it to the columns collection of the DataGrid named "targetDataGrid".
<data:DataGrid x:Name="targetDataGrid"> <data:DataGrid.Columns> <data:DataGridCheckBoxColumn Header="Available " Binding="{Binding Available}" /> </data:DataGrid.Columns> </data:DataGrid>
C#
using System.Windows.Data;
...
DataGridCheckBoxColumn checkBoxColumn = new DataGridCheckBoxColumn(); checkBoxColumn.Header = "Available"; checkBoxColumn.Binding = new Binding("Available"); targetDataGrid.Columns.Add(checkBoxColumn);
The following creates a DataGridTemplateColumn bound to the Birthday property with a header of "Birthday", and adds it to the columns collection of the DataGrid named "targetDataGrid".
<UserControl.Resources> <local:DateTimeConverter x:Key="DateConverter" /> </UserControl.Resources>
...
<data:DataGrid x:Name="targetDataGrid" AutoGenerateColumns="False" > <data:DataGrid.Columns> <data:DataGridTemplateColumn Header="Birthday"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Birthday, Converter={StaticResource DateConverter}}" Margin="4"/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <basics:DatePicker SelectedDate="{Binding Birthday, Mode=TwoWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid>
There are two ways to dynamically create a template column for a DataGrid. One is to load in the CellTemplate and CellEditingTemplates as DataTemplates from resources, and the other is to construct the DataTemplates on the fly using XamlReader.
1. Resources Method
This method creates the CellTemplate DataTemplate and the CellEditingTemplate DataTemplate in XAML and stores them as named resources. Then when the column is created the DataTemplates are used.
Use the below XAML to create the DataTemplates as resources to support the code for this method.
<UserControl.Resources> <local:DateTimeConverter x:Key="DateConverter" /> <DataTemplate x:Key="myCellTemplate"> <TextBlock Text="{Binding Birthday, Converter={StaticResource DateConverter}}" Margin="4"/> </DataTemplate> <DataTemplate x:Key="myCellEditingTemplate"> <basics:DatePicker SelectedDate="{Binding Birthday, Mode=TwoWay}" /> </DataTemplate> </UserControl.Resources>
C#
using System.Windows.Data;
...
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn(); templateColumn.Header = "Birthday"; templateColumn.CellTemplate = (DataTemplate)Resources["myCellTemplate"]; templateColumn.CellEditingTemplate = (DataTemplate)Resources["myCellEditingTemplate"]; targetDataGrid.Columns.Add(templateColumn);
2. XamlReader Method
This method creates the DataTemplate inline using the XamlReader class. This class takes a string and parses it to try to build a visual tree. In this case we are creating DataTemplates. This method is especially useful if the DataTemplate itself has to be dynamic. One example being if you wanted to modify what the element in the template was bound to.
Warning: This method is considerably more difficult than the resources method. I recommend only using this if you need to dynamically create the DataTemplate.
Some things to watch out for:
Now that the warnings are out of the way, here is how you do the equivalent of the code above:
C#
using System.Windows.Data; using System.Windows.Markup; using System.Text;
...
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn(); templateColumn.Header = "Birthday"; StringBuilder CellTemp = new StringBuilder(); CellTemp.Append("<DataTemplate "); CellTemp.Append("xmlns='http://schemas.microsoft.com/winfx/"); CellTemp.Append("2006/xaml/presentation' "); CellTemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' "); //Be sure to replace "YourNamespace" and "YourAssembly" with your app's //actual namespace and assembly here CellTemp.Append("xmlns:local = 'clr-namespace:YourNamespace"); CellTemp.Append(";assembly=YourAssembly'>"); CellTemp.Append("<Grid>"); CellTemp.Append("<Grid.Resources>"); CellTemp.Append("<local:DateTimeConverter x:Key='DateConverter' />"); CellTemp.Append("</Grid.Resources>"); CellTemp.Append("<TextBlock "); CellTemp.Append("Text = '{Binding Birthday, "); CellTemp.Append("Converter={StaticResource DateConverter}}' "); CellTemp.Append("Margin='4'/>"); CellTemp.Append("</Grid>"); CellTemp.Append("</DataTemplate>"); StringBuilder CellETemp = new StringBuilder(); CellETemp.Append("<DataTemplate "); CellETemp.Append("xmlns='http://schemas.microsoft.com/winfx/"); CellETemp.Append("2006/xaml/presentation' "); CellETemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' "); CellETemp.Append("xmlns:basics='clr-namespace:System.Windows.Controls;"); CellETemp.Append("assembly=System.Windows.Controls' >"); CellETemp.Append("<basics:DatePicker "); CellETemp.Append("SelectedDate='{Binding Birthday, Mode=TwoWay}' />"); CellETemp.Append("</DataTemplate>"); templateColumn.CellTemplate = (DataTemplate)XamlReader.Load(CellTemp.ToString()); templateColumn.CellEditingTemplate = (DataTemplate)XamlReader.Load(CellETemp.ToString()); targetDataGrid.Columns.Add(templateColumn);
个人感觉还是载入样式好一些!