惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
C
Cybersecurity and Infrastructure Security Agency CISA
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
T
Threat Research - Cisco Blogs
C
Cisco Blogs
Recent Announcements
Recent Announcements
S
Securelist
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
P
Privacy & Cybersecurity Law Blog
宝玉的分享
宝玉的分享
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 热门话题
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
月光博客
月光博客
AWS News Blog
AWS News Blog
P
Proofpoint News Feed
博客园 - 司徒正美
L
LINUX DO - 最新话题
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
H
Help Net Security
Spread Privacy
Spread Privacy
PCI Perspectives
PCI Perspectives
Project Zero
Project Zero
I
Intezer
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
The Last Watchdog
The Last Watchdog
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
Recorded Future
Recorded Future
T
Tenable Blog
Jina AI
Jina AI
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志

博客园 - 蓝色飞翔

Exchange Server 2010 收发传真 强大的Exchange 动态邮件通讯组 在Exchange 服务器上查看当前在线人数 C# 建立AD帐号,设置下次登录修改密码 Office 2010 试用版可以直接激活为正式版。 Windows 7 企业版(90天试用版)可以直接激活为正式版..附激活过程 在XP下重装TCPIP协议? 发展改革委--吃屎。 英文不懂这些,弄错会很丢脸的 China GDP Microsoft 又出好東西了! Silverlight DataGrid (2) Silverlight DataGrid(1) 网络负载平衡(NLB)详解 把NOTES 部署到GAC中. - 蓝色飞翔 - 博客园 WF + Infopath(5)部署 - 蓝色飞翔 WF + Infopath(4)編碼 - 蓝色飞翔 WF + Infopath(3)設計InfoPath - 蓝色飞翔 WF + Infopath(2)設計工作流
Silverlight DataGrid(3)
蓝色飞翔 · 2008-06-05 · via 博客园 - 蓝色飞翔

Defining Silverlight DataGrid Columns at Runtime

Now that you know the basics of the Silverlight DataGrid and how to specify the Columns in XAML, you might want to customize your DataGrid's columns at runtime.

This process is pretty straight forward, so instead of doing the usual end-to-end walk through, I'm going to provide you with a Rosetta Stone between the static XAML form and the dynamic C#/VB form for the scenario in the last post.

Defining a DataGrid

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;
LayoutRoot.Children.Add(targetDataGrid);

VB

Dim targetDataGrid As New DataGrid
targetDataGrid.ItemsSource = Source
LayoutRoot.Children.Add(targetDataGrid)

Defining a DataGrid Text Column

The following creates a DataGridTextBoxColumn bound to the FirstName property with a header of "First Name", and adds it to the columns collection of the DataGrid named "targetDataGrid".

Static

<my:DataGrid x:Name="targetDataGrid">
<
my:DataGrid.Columns>
<
my:DataGridTextBoxColumn Header="First Name"
DisplayMemberBinding="{Binding FirstName}" />
</
my:DataGrid.Columns>
</
my:DataGrid>

Dynamic

C#

using System.Windows.Data;

...

DataGridTextBoxColumn textBoxColumn = new DataGridTextBoxColumn();
textBoxColumn.Header = "First Name";
textBoxColumn.DisplayMemberBinding = new Binding("FirstName");
targetDataGrid.Columns.Add(textBoxColumn);

VB

Imports System.Windows.Data

...

Dim TextBoxColumn As New DataGridTextBoxColumn
TextBoxColumn.Header = "First Name"
TextBoxColumn.DisplayMemberBinding = New Binding("FirstName")
TargetDataGrid.Columns.Add(TextBoxColumn)

Defining a DataGrid CheckBox Column

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".

Static

<my:DataGrid x:Name="targetDataGrid">
<
my:DataGrid.Columns>
<
my:DataGridCheckBoxColumn Header="Available "
DisplayMemberBinding="{Binding Available}" />
</
my:DataGrid.Columns>
</
my:DataGrid>

Dynamic

C#

using System.Windows.Data;

...

DataGridCheckBoxColumn checkBoxColumn = new DataGridCheckBoxColumn();
checkBoxColumn.Header = "Available";
checkBoxColumn.DisplayMemberBinding = new Binding("Available");
targetDataGrid.Columns.Add(checkBoxColumn);

VB

Imports System.Windows.Data

...

Dim CheckBoxColumn As New DataGridCheckBoxColumn
CheckBoxColumn.Header = "Available"
CheckBoxColumn.DisplayMemberBinding = New Binding("Available")
targetDataGrid.Columns.Add(CheckBoxColumn)

Defining a DataGrid Template Column

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".

Static

<UserControl.Resources>
<
local:DateTimeConverter x:Key="DateConverter" />
</
UserControl.Resources>

...

<my:DataGrid x:Name="targetDataGrid" AutoGenerateColumns="False" >
<
my:DataGrid.Columns>
<
my:DataGridTemplateColumn Header="Birthday">
<
my:DataGridTemplateColumn.CellTemplate>
<
DataTemplate>
<
TextBlock
Text="{Binding Birthday,
Converter={StaticResource DateConverter}}"
FontFamily="Trebuchet MS" FontSize="11"
Margin="5,4,5,4"/>
</
DataTemplate>
</
my:DataGridTemplateColumn.CellTemplate>
<
my:DataGridTemplateColumn.CellEditingTemplate>
<
DataTemplate>
<
DatePicker
SelectedDate="{Binding Birthday, Mode=TwoWay}" />
</
DataTemplate>
</
my:DataGridTemplateColumn.CellEditingTemplate>
</
my:DataGridTemplateColumn>
</
my:DataGrid.Columns>
</
my:DataGrid>

Dynamic

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}}"
FontFamily="Trebuchet MS" FontSize="11"
Margin="5,4,5,4"/>
</
DataTemplate>

<

DataTemplate x:Key="myCellEditingTemplate">
<
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);

VB

Imports System.Windows.Data

...

Dim TemplateColumn As New DataGridTemplateColumn
TemplateColumn.Header = "Birthday"
TemplateColumn.CellTemplate = Resources("myCellTemplate")
TemplateColumn.CellEditingTemplate = 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 data 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:

  1. You will need to declare any XAML namespace that is used in the data template
  2. Any custom XAML namespace needs to specify both the clr-namespace and the assembly
  3. You cannot have white space between the xmlns: and the name of your namespace
  4. External resources cannot be referenced, they need to be declared inline
  5. The entire template is a single line, so if you get a XAML Parse exception, it will always say line 1, however the character is fairly accurate if you were to concatenate all of your lines.
  6. When using the StringBuilder approach shown below, make sure that you have the correct white space at the end of a line so that it is correctly separated when concatenated with the next line.

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/client/2007' ");
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("FontFamily='Trebuchet MS' FontSize='11' ");
CellTemp.Append("Margin='5,4,5,4'/>");
CellTemp.Append("</Grid>");
CellTemp.Append("</DataTemplate>");

StringBuilder CellETemp = new StringBuilder();
CellETemp.Append("<DataTemplate ");
CellETemp.Append("xmlns='http://schemas.microsoft.com/client/2007' ");
CellETemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>");
CellETemp.Append("<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);

VB

Imports System.Windows.Data
Imports System.Text
Imports System.Windows.Markup

...

Dim TemplateColumn As New DataGridTemplateColumn
TemplateColumn.Header = "Birthday"Dim CellTemp As New StringBuilder
CellTemp.Append("<DataTemplate ")
CellTemp.Append("xmlns = 'http://schemas.microsoft.com/client/2007' ")
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("FontFamily='Trebuchet MS' FontSize='11' ")
CellTemp.Append("Margin='5,4,5,4'/>")
CellTemp.Append("</Grid>")
CellTemp.Append("</DataTemplate>")

Dim CellETemp As New StringBuilder
CellETemp.Append("<DataTemplate ")
CellETemp.Append("xmlns = 'http://schemas.microsoft.com/client/2007' ")
CellETemp.Append("xmlns:x = 'http://schemas.microsoft.com/winfx/2006/xaml'>")
CellETemp.Append("<DatePicker ")
CellETemp.Append("SelectedDate='{Binding Birthday, Mode=TwoWay}' />")
CellETemp.Append("</DataTemplate>")

TemplateColumn.CellTemplate = XamlReader.Load(CellTemp.ToString())
TemplateColumn.CellEditingTemplate = XamlReader.Load(CellETemp.ToString())
targetDataGrid.Columns.Add(TemplateColumn)

Up next time - a reason to dynamically define columns at runtime: responding to the AutoGeneratingColumn event.

Posted: Monday, April 14, 2008 3:25

源文档 <http://blogs.msdn.com/scmorris/archive/2008/04/14/defining-silverlight-datagrid-columns-at-runtime.aspx>