Combine DataGridCheckBoxColumn and DataGridTextColumn to one class?
From what I used in Telerik's GridView control, I can dynamically add a column DataGridColumn (forgot the extact class name) into the GridView, if the binding object is bool then it will use CheckBox to display, otherwise will use text to display.
Now I switched to use Silverlight's basic DataGrid control, I wonder if I can write a single class and do the same thing?
Gr开发者_运维百科idView.Columns.Add(new DataGridColumn(){Binding = new Binding("boolType"), Header="Bool Type"});
GridView.Columns.Add(new DataGridColumn(){Binding = new Binding("StringType"), Header="String Type"});
Thanks in advance.
King
Yes, this can be done, but you will need slightly more than just a "single class". The technique is based on DataGridTemplateColumn
where we will choose a template for each column based upon it's type.
1) You will need a helper class which will decide which template to choose:
public class ColumnTemplateSelector : ContentControl
{
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
switch (newContent.GetType().Name)
{
case "Boolean":
ContentTemplate = Application.Current.Resources["BooleanDataTemplate"] as DataTemplate;
break;
case "String":
default:
ContentTemplate = Application.Current.Resources["StringDataTemplate"] as DataTemplate;
break;
}
}
}
I know, this could be done better but i think it's simple enough to notice what it's all about, it can be extended, optimized etc.
2) Add the Content Templates to your App.xaml
File, they might look like this (simple example, you might want to modify them):
<Application.Resources>
<DataTemplate x:Key="BooleanDataTemplate">
<CheckBox IsChecked="{Binding}" />
</DataTemplate>
<DataTemplate x:Key="StringDataTemplate">
<TextBlock Text="{Binding}" />
</DataTemplate>
</Application.Resources>
3) Now we can setup the DataGrid
. One caveat is that we'll need to define our columns, we cannot use the AutoGenerateColumns
feature. Ok, here is the example code. First, add the Namespace where the ColumnTemplateSelector
(see 1.) was defined, to your MainPage.xaml
(or whereever you need it):
xmlns:local="clr-namespace:MySilverlightExample"
Assumed that our class (call it "Person") has three columns: "Name", "Age" and "IsMarried" (is bool
actually), your table looks like this:
<sdk:DataGrid ItemsSource="{Binding MyListOfPersonItems}" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:ColumnTemplateSelector Content="{Binding Name}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:ColumnTemplateSelector Content="{Binding Age}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:ColumnTemplateSelector Content="{Binding IsMarried}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
Maybe there is a shorter syntax how it can be written but this is how it would basically work, just tested it here and worked like a charm.
Hope this helps!
精彩评论