1. 程式人生 > >WPF-DataGrid後臺動態生成列

WPF-DataGrid後臺動態生成列

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)

相關推薦

WPF-DataGrid後臺動態生成

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 ru

DataGrid後臺動態生成

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 run

datagrid動態生成

Oracle將資料進行行轉列:http://blog.csdn.net/u013533810/article/details/37956195 1、程式中的條件引數 string WhereStr = context.Request[

Silverlight中DataGrid控制元件動態生成並結合DataPager進行分頁

1、準備一個實體類 using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> ///電流資料 的摘要說明 /// <

前端資料傳到後臺動態生成Excel檔案並提供檔案下載

需求描述: 需要將前端的某些資料生成Excel檔案,並提供下載功能。 解決方案: 前端通過ajax的方式將資料資訊傳到後臺,後臺使用POI元件動態生成Excel檔案流,並寫入資料資訊,返回前端供前端下載。 程式碼示例:

WPF 資料庫獲得的資料DataTable繫結到DataGrid進行介面顯示,自動生成頭。

一般在WPF使用DataGrid時,在Xaml頁面定義各個列頭和繫結資料來源。 從資料庫讀取的資料DataTable也可以直接繫結DataGrid。 1、在Xaml拖一個DataGrid。 2、得到DataTable       宣告DataTable

WPF DataGrid隱藏某 DataGridTextColumn動態繫結轉換器

需求:根據另一控制元件改變DataGrid某列的可見性(Collapsed/Hidden/Visible)原本 繫結欄位是這樣寫的:Visibility="{Binding ElementName=sample,Path=IsChecked,Converter={Static

WPF後臺獲取DataGrid的繫結欄位。

前臺: <DataGrid Name="dg" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn B

WPF DataGrid的DataGridCheckBoxColumn前臺勾選後對應的綁定數據並未更新

.com msd 問題 模式 https date tps binding 時間 WPF用的時間也不短了,還是遇到一些低級問題,好慚愧。 問題是這樣的,WPF的DataGrid中,DataGridCheckBoxColumn列綁定了數據源中的一個boo類型的字段,模式為T

Jqgrid中動態生成colModel實現雙擊編輯整時,鼠標定位在當前雙擊指定單元格

jqGrid使用鼠標定位雙擊的單元格通過配置ondbclick事件來實現雙擊功能ondblClickRow:function(rowid,iRow,iCol,e) {//獲取表格的初始model var colModel =$(TableId).jqG

C# winform 後臺控制刪除動態生成的控制元件

RadioButton是由資料庫列表資料讀出來,放到panelEx2上的,現在區域性重新整理,需要刪除這些RadioButton,重新新增。   List<Control> removeList = new List<Control>(); for (int i = 0;

Django 許可權管理-後臺根據使用者許可權動態生成選單

Django許可權管理 實現目標: 1、管理使用者,新增角色,使用者關聯角色 2、新增許可權、角色關聯許可權 3、新增動作、許可權關聯動作 4、新增選單、許可權關聯選單 實現動態生成使用者許可權選單(可設定多級選單巢狀)、根據前臺URL自動選中選單並摺疊其餘選單 最終實現類似這樣的效果: 選單一   選

C# WPF DataGrid 根據某的值設定行的背景色

最簡單的方法是 使用 datagrid的LoadingRow事件。 private void datagrid_LoadingRow(object sender, DataGridRowEventArgs e) { var

easyui之datagrid動態修改

easyui datagrid 定義列的方式通常是: [html] view plain copy print? $('#grid').datagrid({columns:[[        {field:'f1',title:'欄位1',width:160},        {field:'

WPF中TreeView控制元件資料繫結和後臺動態新增資料

資料繫結: TreeView資料繫結需要使用層次結構資料模板(HierarchicalDataTemplate)來顯示分層資料。XAML程式碼如下: <TreeView Name="chapterTree" Grid.Column="0"> <TreeVie

php後臺管理,結合許可權,動態生成欄目列表

思路:獲取許可權,生成父類欄目,在判斷子欄目是不是在許可權中,在的話,就拼接成html,返回,最後拼接父類欄目 返回 /** * 返回org html * @return string */ public static function getOrgMe

WPF DataGrid的屬性繫結問題

WPF中的DataGrid中Column的IsReadOnly和VIsibility等屬性繫結時,總沒有任何效果,輸出裡也顯示找不到,搜了半天才發現,原來Column不屬於visual 或 logical tree,所以不能在樹上搜索他的繫結源,需要藉助其他方法給屬性指定資

easyui 動態生成datagrid

function getItemTable(id, type) { tabInfoItem.datagrid({ url:'', data: [], columns: [[

ajax請求後臺得到json資料後動態生成樹形下拉框

<select id="cc" class="easyui-combotree" style="width:580px;" name="rempId"  data-options="required:true"></select> <scri

wpf datagrid 中按鈕 動態顯示

//若datagrid出現滾動條可能會出現問題需要加上下面倆句話。 //因為出滾動條時,為了顯示加速,datagrid會載入一部分資料。另一些資料當滾動時在載入進去 這樣初始化獲取不到這些資料。 //在datagrid上新增上以下倆句話可以避免預載入資料,使資料全部加載出來