因爲項目須要製做一個可通用的報表多行標題,且可實現各類類型的內容顯示,包括文本、輸入框、下拉框、多選框等(自定的顯示內容可自行擴展),並支持參數綁定轉換,效果以下: app
源碼結構ui
ColumnItem類:對列的寬度,對象方式,顯示類型,綁定名稱,converter資源進行設置this
/// <summary> /// 描述 <see cref="ColumnItem"/> 動態列項目,用於在後臺構建多列標題綁定項 /// </summary> [Serializable] public sealed class ColumnItem : NotifyPropertyChangedBase, ICloneable { /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例,通常用於頂級標題欄 /// </summary> /// <param name="name">默認列名</param> public ColumnItem(String name) : this(name, "") { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="bindingName">綁定名稱</param> public ColumnItem(String name, String bindingName) : this(name, bindingName, "", "", HorizontalAlignment.Left, 80) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> /// <param name="visibility">是否顯示</param> public ColumnItem(String name, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width, Visibility visibility) : this(name, "", bindingName, converterResourceKey, stringFormat, alignment, width, visibility, ColumnType.TextBlock) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> public ColumnItem(String name, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width) : this(name, "", bindingName, converterResourceKey, stringFormat, alignment, width, Visibility.Visible, ColumnType.TextBlock) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="extendName">擴展列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> public ColumnItem(String name, String extendName, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width) : this(name, extendName, bindingName, converterResourceKey, stringFormat, alignment, width, Visibility.Visible, ColumnType.TextBlock) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> /// <param name="columnType">數據模板內容類型</param> public ColumnItem(String name, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width, ColumnType columnType) : this(name, "", bindingName, converterResourceKey, stringFormat, alignment, width, Visibility.Visible, columnType) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="extendName">擴展列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> /// <param name="columnType">數據模板內容類型</param> public ColumnItem(String name, String extendName, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width, Visibility visibility) : this(name, extendName, bindingName, converterResourceKey, stringFormat, alignment, width, visibility, ColumnType.TextBlock) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="extendName">擴展列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> /// <param name="columnType">數據模板內容類型</param> public ColumnItem(String name, String extendName, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width, ColumnType columnType) : this(name, extendName, bindingName, converterResourceKey, stringFormat, alignment, width, Visibility.Visible, columnType) { } /// <summary> /// 實例化 <see cref="ColumnItem"/> 類新實例 /// </summary> /// <param name="name">默認列名</param> /// <param name="extendName">擴展列名</param> /// <param name="bindingName">綁定名稱</param> /// <param name="converterResourceKey">綁定的資源鍵(傳遞此資源時,要在資源中聲明)</param> /// <param name="stringFormat">字符串格式</param> /// <param name="alignment">對齊方式</param> /// <param name="width">列寬</param> /// <param name="visibility">是否顯示</param> /// <param name="columnType">數據模板內容類型</param> public ColumnItem(String name, String extendName, String bindingName, String converterResourceKey, String stringFormat, HorizontalAlignment alignment, int width, Visibility visibility, ColumnType columnType) { this.ID = Guid.NewGuid(); if (String.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException("titleName", "標題不能爲 null 或 空白字符串。"); } this.Name = name; this.ExtendName = extendName; this.BindingName = (String.IsNullOrWhiteSpace(bindingName)) ? "simple" : bindingName; this.ConverterResourceKey = converterResourceKey; this.StringFormat = stringFormat; this.Alignment = alignment; this.Width = width; this.Visibility = visibility; this.Type = columnType; this.Columns = new ColumnItemCollection(this); //初始化 this.Level = 0; //默認 this.TextWrapping = System.Windows.TextWrapping.NoWrap; } private Int32 mWidth; private Visibility mVisibility; private HorizontalAlignment mAlignment; public Guid ID { get; private set; } /// <summary> /// 列寬 /// </summary> public Int32 Width { get { return mWidth; } set { mWidth = value; OnPropertyChanged("Width"); } } /// <summary> /// 列顯示 /// </summary> public Visibility Visibility { get { return mVisibility; } set { mVisibility = value; OnPropertyChanged("Visibility"); } } /// <summary> /// 獲取或設置水平對齊方式 /// </summary> public HorizontalAlignment Alignment { get { return mAlignment; } set { mAlignment = value; OnPropertyChanged("Alignment"); } } /// <summary> /// 默認列名 /// </summary> public String Name { get; private set; } /// <summary> /// 擴展列名 /// </summary> public String ExtendName { get; set; } /// <summary> /// 綁定名稱 /// </summary> public String BindingName { get; set; } /// <summary> /// 獲取或設置轉換資源鍵 /// </summary> public String ConverterResourceKey { get; set; } /// <summary> /// 獲取或設置字符串格式 /// </summary> public String StringFormat { get; set; } /// <summary> /// 控件類型 /// </summary> public ColumnType Type { get; set; } /// <summary> /// 獲取或設置是否自動換行(默認爲 NoWrap) /// </summary> public TextWrapping TextWrapping { get; set; } public ColumnComboBox ColumnComboBox { get; set; } /// <summary> /// 獲取列集合 /// </summary> public ColumnItemCollection Columns { get; private set; } /// <summary> /// 獲取級別 /// </summary> public int Level { get; internal set; } /// <summary> /// 獲取父級 /// </summary> public ColumnItem Parent { get; internal set; } /// <summary> /// 獲取子級深度 /// </summary> /// <returns></returns> public int ChildLevelDepth() { if (this.Columns.Count > 0) { return this.CalcLevelDepth(true) - this.Level; } else { return 0; } } /// <summary> /// 計算獲取級別深度 /// </summary> /// <param name="child">計算子級</param> /// <returns></returns> private int CalcLevelDepth(bool child) { if (this.Columns.Count > 0) { int level = this.Columns.Max(c => c.CalcLevelDepth(child)); if (child) { return level; } else { return level - this.Level; } } else { return this.Level; } } /// <summary> /// 獲取當前列的全部最後子集的總數 /// </summary> /// <returns></returns> public int LastLevelColumnCount() { int value = 0; if (this.Columns.Count > 0) { value += this.Columns.Sum(c => c.LastLevelColumnCount()); } else { value = 1; } return value; } /// <summary> /// 合計總寬度 /// </summary> /// <returns></returns> public int TotalGroupWidth() { int value; if (this.Columns.Count > 0) { value = this.Columns.Sum(c => c.TotalGroupWidth()); } else { value = this.Width; } return value; } /// <summary> /// 驗證(必須設置綁定值) /// </summary> internal void CreateVerify() { if (this.Columns.Count == 0) { if (String.IsNullOrWhiteSpace(this.BindingName)) { throw new ArgumentNullException(String.Format("{0} 爲末級時,綁定路徑 BindingPath 爲 null 或空白字符串。", this.Name)); } } } public void SetColumnComboBox(ColumnComboBox columnComboBox) { this.ColumnComboBox = columnComboBox; } #region ICloneable ColumnItem 對象深度複製 public object Clone() { ColumnItem item = (ColumnItem)this.MemberwiseClone(); item.Parent = null; item.Name = this.Name; item.ExtendName = this.ExtendName; item.Columns = new ColumnItemCollection(item); foreach (var o in this.Columns) { var _o = (ColumnItem)o.Clone(); _o.Parent = null; item.Columns.Add(_o); } return item; } private void OnClone(ColumnItemCollection collection, ColumnItemCollection collection2) { foreach (var item in collection2) { var _o = (ColumnItem)item.Clone(); if (item.Columns.Count > 0) { OnClone(item.Columns, item.Columns); } collection.Add(_o); } } #endregion } [Serializable] public class ColumnComboBox : NotifyPropertyChangedBase { public ColumnComboBox(String comboBoxBindName) : this(comboBoxBindName, "", "", "") { } public ColumnComboBox(String comboBoxBindName, String selectedItemBindName) : this(comboBoxBindName, selectedItemBindName, "", "") { } public ColumnComboBox(String comboBoxBindName, String selectedItemBindName, String selectedValuePath, String displayMemberPath) { this.mComboBoxBindName = comboBoxBindName; this.mSelectedItemBindName = selectedItemBindName; this.mSelectedValuePath = selectedValuePath; this.mDisplayMemberPath = displayMemberPath; } private String mSelectedItemBindName; private String mComboBoxBindName; private String mSelectedValuePath = ""; private String mDisplayMemberPath = ""; private ObservableCollection<string> itemSource; // /// <summary> /// 綁定資源 /// </summary> public String ComboBoxBindName { get { return mComboBoxBindName; } set { mComboBoxBindName = value; } } /// <summary> /// 選中值 /// </summary> public string SelectedValuePath { get { return mSelectedValuePath; } set { mSelectedValuePath = value; } } /// <summary> /// 顯示值 /// </summary> public string DisplayMemberPath { get { return mDisplayMemberPath; } set { mDisplayMemberPath = value; } } public string SelectedItemBindName { get { return mSelectedItemBindName; } set { mSelectedItemBindName = value; } } }
報表內容中須要其餘類型時,擴展IDataGridDataTemplateService接口spa
/// <summary> /// <see cref="DataGrid"/>控件數據模板<see cref="DataTemplate"/>構建服務, /// 根據<see cref="DataTemplate"/>的內容多樣性構建不一樣的顯示控件,主要針對單一控件顯示 /// </summary> public interface IDataGridDataTemplateService { /// <summary> /// 動態構內容綁定模板 /// </summary> /// <param name="column">自定義列信息</param> /// <param name="bindingParameter">是否參數轉換</param> /// <param name="gridColum">綁定的子列索引 </param> /// <returns></returns> String CreateCellXaml(ColumnItem column, bool bindingParameter, int? gridColum); }
DataGridTemplateColumnHelper核心類,組織動態的列標題以及綁定列,可在下載源碼參考。3d
/// <summary> /// 自定義模板列構建幫助類 /// </summary> internal static class DataGridTemplateColumnHelper { /// <summary> /// 設置標題Grid列寬度,組織出一個複雜的標題格式 /// </summary> /// <param name="sbStr">標題字符串</param> /// <param name="column">列</param> /// <param name="index">列索引,用於控制標題內容顯示的邊線</param> private static void SetColumnDefinition(StringBuilder sbStr, ColumnItem column, ref int index) { if (column.Columns.Count > 0) { foreach (var item in column.Columns) { SetColumnDefinition(sbStr, item, ref index); } } else //默認包含一列 { if (index > 0) //當index>0時,添加一個右側的Rectangle矩形圖形邊線位置,默認是左側和右側是不繪製邊線 { sbStr.AppendLine("<ColumnDefinition Width=\"1\" />"); } //添加一個標題的顯示內容列,並設置固定寬度 sbStr.AppendLine(String.Format("<ColumnDefinition Width=\"{0}*\"/>", column.Width)); index++; } } /// <summary> /// 設置標題內容 /// </summary> /// <param name="sbStr"></param> /// <param name="column">當前列</param> /// <param name="totalcolumnCount">總列數</param> /// <param name="colIndex">內容索引列</param> private static void SetContentPresenter(StringBuilder sbStr, ColumnItem column, int totalcolumnCount, ref int colIndex) { //計算出當前列所佔的Grid的ColumnDefinition數目 int columnOffset = column.LastLevelColumnCount() * 2 - 1; //計算當前列在整個標題中的標題行深度 int LevelDepth = column.Parent.ChildLevelDepth(); //用於控制繪製標題內容下面顯示下線,以及當前顯示標題的Grid.RowSpan int rowOffset; //通常狀況默認爲1 if (column.Columns.Count == 0)// { rowOffset = LevelDepth * 2 - 1; } else { rowOffset = 1; // } //計算出當前標題在第幾個RowDefinition畫內容下邊線 int lineRow = (column.Level * 2 + 1) + (rowOffset - 1); //計算出當前標題在第幾個ColumnDefinition畫內容右邊線 int lineColumn = (colIndex + 1) + (columnOffset - 1); //畫標題,並設置當前標題在Grid中的定位 sbStr.AppendLine( CreateDataGridTemplateColumnHeaderContent( String.IsNullOrWhiteSpace(column.ExtendName) ? column.Name : column.ExtendName, //標題顯示內容 column.Level * 2, //所屬行,標題內容顯示的Grid.Row rowOffset, //標題內容顯示的Grid.RowSpan colIndex, //標題內容顯示的Grid.Column列 columnOffset //標題內容顯示的Grid.ColumnSpan )); //存在子級,時添加下線 if (column.Columns.Count > 0) { sbStr.AppendLine(String.Format("<Rectangle Fill=\"#FFC9CACA\" VerticalAlignment=\"Stretch\" Height=\"1\" Grid.Row=\"{0}\" Grid.Column=\"{1}\" Grid.RowSpan=\"{2}\" Grid.ColumnSpan=\"{3}\" />", lineRow, colIndex, 1, columnOffset)); } //標題右側下線 if (lineColumn < (totalcolumnCount * 2 - 1)) { sbStr.AppendLine(String.Format("<Rectangle Fill=\"#FFC9CACA\" VerticalAlignment=\"Stretch\" Width=\"1\" Visibility=\"Visible\" Grid.Row=\"{0}\" Grid.Column=\"{1}\" Grid.RowSpan=\"{2}\" Grid.ColumnSpan=\"{3}\" />", column.Level * 2, lineColumn, rowOffset, 1)); } //存在子級,先從子級起畫 if (column.Columns.Count > 0) { foreach (var item in column.Columns) { SetContentPresenter(sbStr, item, totalcolumnCount, ref colIndex); } } else { colIndex += 2; //含分隔線 } } /// <summary> /// 設置單元格綁定 /// </summary> /// <param name="sbStr"></param> /// <param name="column"></param> /// <param name="bindingParameter"></param> /// <param name="index"></param> private static void SetCellBinding(StringBuilder sbStr, ColumnItem column, bool bindingParameter, ref int index) { if (column.Columns.Count > 0) { foreach (var item in column.Columns) { SetCellBinding(sbStr, item, bindingParameter, ref index); } } else { if (index > 0) { sbStr.AppendLine(String.Format("<Rectangle Fill=\"#FFC9CACA\" VerticalAlignment=\"Stretch\" Grid.Column=\"{0}\"/>", index)); index++; } //構建指定類型的項綁定 IDataGridDataTemplateFactory templateFactory = ServiceFactory.GetService<IDataGridDataTemplateFactory>(); IDataGridDataTemplateService templateService = templateFactory.GetService(column.Type); sbStr.AppendLine(templateService.CreateCellXaml(column, bindingParameter, index)); index++; } } /// <summary> /// 設置單元格列寬 /// </summary> /// <param name="sbStr"></param> /// <param name="column"></param> /// <param name="index"></param> private static void SetCellColumnDefinition(StringBuilder sbStr, ColumnItem column, ref int index) { if (column.Columns.Count > 0) { foreach (var item in column.Columns) { SetCellColumnDefinition(sbStr, item, ref index); } } else { if (index > 0) { sbStr.AppendLine("<ColumnDefinition Width=\"1\" />"); } sbStr.AppendLine(String.Format("<ColumnDefinition Width=\"{0}*\"/>", column.Width)); index++; } } /// <summary> /// 建立組列 /// </summary> /// <param name="column">列</param> /// <param name="bindingParameter">是不是參數</param> /// <returns></returns> public static DataGridTemplateColumn CreateTemplateGroupColumn(ColumnItem column, bool bindingParameter) { var templateColumn = new DataGridTemplateColumn(); //當前列包含的子級深度 int LevelDepth = column.ChildLevelDepth(); //獲取當前列子級的總列數 int totalcolumnCount = column.LastLevelColumnCount(); // //設置當前列的寬度 templateColumn.Width = new DataGridLength(column.TotalGroupWidth() + LevelDepth); //構建HeaderStyle以及CellTemplate模板 //動態構建標題樣式 DataGridTemplateColumn.HeaderStyle #region 構建多行標題 var sbHeaderStr = new StringBuilder(); sbHeaderStr.AppendLine("<Grid.RowDefinitions>"); for (int i = 0; i <= LevelDepth; i++) { if (i > 0) { sbHeaderStr.AppendLine("<RowDefinition Height=\"1\" />"); //構建分割線, } if (i < LevelDepth) { sbHeaderStr.AppendLine("<RowDefinition Height=\"25\" />"); //內容區域 } else { sbHeaderStr.AppendLine("<RowDefinition Height=\"*\" MinHeight=\"25\"/>"); //內容區域 } } sbHeaderStr.AppendLine("</Grid.RowDefinitions>"); sbHeaderStr.AppendLine("<Grid.ColumnDefinitions>"); int index = 0; foreach (var item in column.Columns) { SetColumnDefinition(sbHeaderStr, item, ref index); } sbHeaderStr.AppendLine("</Grid.ColumnDefinitions>"); int columnOffset = totalcolumnCount * 2 - 1; sbHeaderStr.AppendLine(CreateDataGridTemplateColumnHeaderContent(String.IsNullOrWhiteSpace(column.ExtendName) ? column.Name : column.ExtendName, -1, -1, -1, columnOffset)); sbHeaderStr.AppendLine(String.Format("<Rectangle Fill=\"#FFC9CACA\" VerticalAlignment=\"Stretch\" Height=\"1\" Grid.Row=\"1\" Grid.ColumnSpan=\"{0}\" />", columnOffset)); index = 0; foreach (var item in column.Columns) { SetContentPresenter(sbHeaderStr, item, totalcolumnCount, ref index); } var headerStyleStr = HeaderStyleString(); headerStyleStr = headerStyleStr.Replace("{#content#}", sbHeaderStr.ToString()); templateColumn.HeaderStyle = (Style)XamlReader.Parse(headerStyleStr); #endregion //動態構建綁定DataTemplate DataGridTemplateColumn.CellTemplate #region 構建多行標題數據綁定模板 var sbCellTempStr = new StringBuilder(); sbCellTempStr.AppendLine("<Grid.ColumnDefinitions>"); index = 0; foreach (var item in column.Columns) { SetCellColumnDefinition(sbCellTempStr, item, ref index); } sbCellTempStr.AppendLine("</Grid.ColumnDefinitions>"); index = 0; foreach (var item in column.Columns) { SetCellBinding(sbCellTempStr, item, bindingParameter, ref index); } var cellTemplateStr = CellDataTemplateString(); cellTemplateStr = cellTemplateStr.Replace("{#content#}", sbCellTempStr.ToString()); templateColumn.CellTemplate = (DataTemplate)XamlReader.Parse(cellTemplateStr); #endregion return templateColumn; } /// <summary> /// 動態構建標題模板 /// </summary> /// <param name="sbStr">目標結果</param> /// <param name="title">標題名稱</param> /// <param name="row">所屬Grid行Grid.Row</param> /// <param name="rowSpan">所屬合併行Grid.RowSpan</param> /// <param name="column">所屬Grid列Grid.Column</param> /// <param name="columnSpan">所屬合併列Grid.ColumnSpan</param> private static String CreateDataGridTemplateColumnHeaderContent(String title, int row, int rowSpan, int column, int columnSpan) { StringBuilder sbStr = new StringBuilder(); sbStr.AppendLine("<ContentPresenter VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\""); if (row > 0) { sbStr.AppendFormat(" Grid.Row=\"{0}\"", row); } if (rowSpan > 0) { sbStr.AppendFormat(" Grid.RowSpan=\"{0}\"", rowSpan); } if (column > 0) { sbStr.AppendFormat(" Grid.Column=\"{0}\"", column); } if (columnSpan > 0) { sbStr.AppendFormat(" Grid.ColumnSpan=\"{0}\"", columnSpan); } sbStr.Append(">"); sbStr.AppendLine("<ContentPresenter.Content>"); sbStr.AppendLine(String.Format("<TextBlock Text=\"{0}\" TextAlignment=\"Center\" TextWrapping=\"Wrap\" />", title)); sbStr.AppendLine("</ContentPresenter.Content>"); sbStr.AppendLine("</ContentPresenter>"); return sbStr.ToString(); } /// <summary> /// 建立單列 /// </summary> /// <param name="column"></param> /// <param name="bindingParameter"></param> /// <returns></returns> public static DataGridTemplateColumn CreateTemplateSingleColumn(ColumnItem column, bool bindingParameter) { if (column == null) { throw new ArgumentNullException("column"); } if (String.IsNullOrWhiteSpace(column.BindingName)) { throw new ArgumentNullException("column.BindingName", "末級列的綁定名稱不能爲 null 或空白字符串。"); } //建立DataGrid的列 var templateColumn = new DataGridTemplateColumn(); //設置列的寬度 templateColumn.Width = new DataGridLength(column.Width); //構建模板字符串 var sbStr = new StringBuilder(); //根據模板建立標題 sbStr.AppendLine(CreateDataGridTemplateColumnHeaderContent(String.IsNullOrWhiteSpace(column.ExtendName) ? column.Name : column.ExtendName, -1, -1, -1, -1)); //動態構建標題樣式 DataGridTemplateColumn.HeaderStyle #region DataGridTemplateColumn.HeaderStyle var headerStyleStr = HeaderStyleString(); headerStyleStr = headerStyleStr.Replace("{#content#}", sbStr.ToString()); templateColumn.HeaderStyle = (Style)XamlReader.Parse(headerStyleStr); sbStr.Clear(); #endregion //動態構建綁定DataTemplate DataGridTemplateColumn.CellTemplate #region DataGridTemplateColumn.CellTemplate //構建綁定模板 IDataGridDataTemplateFactory templateFactory = ServiceFactory.GetService<IDataGridDataTemplateFactory>(); IDataGridDataTemplateService templateService = templateFactory.GetService(column.Type); sbStr.AppendLine(templateService.CreateCellXaml(column, bindingParameter, null)); String cellTemplateStr = CellDataTemplateString(); cellTemplateStr = cellTemplateStr.Replace("{#content#}", sbStr.ToString()); templateColumn.CellTemplate = (DataTemplate)XamlReader.Parse(cellTemplateStr); #endregion return templateColumn; } #region 本地資源模板處理 private static object lockObj = new object(); private static String _HeaderStyleString = null; // private static String _CellDataTemplateString = null;// /// <summary> /// 獲取標題樣式 /// </summary> /// <returns></returns> public static String HeaderStyleString() { lock (lockObj) { if (_HeaderStyleString == null) { _HeaderStyleString = GetResourceXamlString("HeaderStyle.xaml"); } return _HeaderStyleString; } } /// <summary> /// 獲取單元格模板字符串 /// </summary> /// <returns></returns> public static String CellDataTemplateString() { lock (lockObj) { if (_CellDataTemplateString == null) { _CellDataTemplateString = GetResourceXamlString("CellDataTemplate.xaml"); } return _CellDataTemplateString; } } /// <summary> /// 獲取資源Xaml字符串 /// </summary> /// <param name="fileName">文件名稱</param> /// <returns></returns> private static String GetResourceXamlString(String fileName) { var res = Application.GetResourceStream(new Uri(String.Format("pack://application:,,,/TGP.DataGridDemo;component/Template/{0}", fileName), UriKind.RelativeOrAbsolute)); using (var sr = new StreamReader(res.Stream)) { return sr.ReadToEnd(); } } #endregion }