WPF报表自定义通用可筛选列头-WPF特工队内部资料

时间:2022-04-13 22:06:08

由于项目需要制作一个可通用的报表多行标题,且可实现各种类型的内容显示,包括文本、输入框、下拉框、多选框等(自定的显示内容可自行扩展),并支持参数绑定转换,效果如下:

  WPF报表自定义通用可筛选列头-WPF特工队内部资料

  WPF报表自定义通用可筛选列头-WPF特工队内部资料

  

  源码结构WPF报表自定义通用可筛选列头-WPF特工队内部资料

ColumnItem类:对列的宽度,对象方式,显示类型,绑定名称,converter资源进行设置

    /// <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, )
{
} /// <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 = ; //默认
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 > )
{
return this.CalcLevelDepth(true) - this.Level;
}
else
{
return ;
}
} /// <summary>
/// 计算获取级别深度
/// </summary>
/// <param name="child">计算子级</param>
/// <returns></returns>
private int CalcLevelDepth(bool child)
{
if (this.Columns.Count > )
{
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 = ;
if (this.Columns.Count > )
{
value += this.Columns.Sum(c => c.LastLevelColumnCount());
}
else
{
value = ;
}
return value;
} /// <summary>
/// 合计总宽度
/// </summary>
/// <returns></returns>
public int TotalGroupWidth()
{
int value;
if (this.Columns.Count > )
{
value = this.Columns.Sum(c => c.TotalGroupWidth());
}
else
{
value = this.Width;
}
return value;
} /// <summary>
/// 验证(必须设置绑定值)
/// </summary>
internal void CreateVerify()
{
if (this.Columns.Count == )
{
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 > )
{
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接口

    /// <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核心类,组织动态的列标题以及绑定列,可在下载源码参考。

    /// <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 > )
{
foreach (var item in column.Columns)
{
SetColumnDefinition(sbStr, item, ref index);
}
}
else //默认包含一列
{
if (index > ) //当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() * - ;
//计算当前列在整个标题中的标题行深度
int LevelDepth = column.Parent.ChildLevelDepth();
//用于控制绘制标题内容下面显示下线,以及当前显示标题的Grid.RowSpan
int rowOffset; //一般情况默认为1
if (column.Columns.Count == )//
{
rowOffset = LevelDepth * - ;
}
else
{
rowOffset = ; //
}
//计算出当前标题在第几个RowDefinition画内容下边线
int lineRow = (column.Level * + ) + (rowOffset - );
//计算出当前标题在第几个ColumnDefinition画内容右边线
int lineColumn = (colIndex + ) + (columnOffset - );
//画标题,并设置当前标题在Grid中的定位
sbStr.AppendLine(
CreateDataGridTemplateColumnHeaderContent(
String.IsNullOrWhiteSpace(column.ExtendName) ? column.Name : column.ExtendName, //标题显示内容
column.Level * , //所属行,标题内容显示的Grid.Row
rowOffset, //标题内容显示的Grid.RowSpan
colIndex, //标题内容显示的Grid.Column列
columnOffset //标题内容显示的Grid.ColumnSpan
));
//存在子级,时添加下线
if (column.Columns.Count > )
{
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, , columnOffset));
}
//标题右侧下线
if (lineColumn < (totalcolumnCount * - ))
{
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 * , lineColumn, rowOffset, ));
}
//存在子级,先从子级起画
if (column.Columns.Count > )
{
foreach (var item in column.Columns)
{
SetContentPresenter(sbStr, item, totalcolumnCount, ref colIndex);
}
}
else
{
colIndex += ; //含分隔线
}
} /// <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 > )
{
foreach (var item in column.Columns)
{
SetCellBinding(sbStr, item, bindingParameter, ref index);
}
}
else
{
if (index > )
{
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 > )
{
foreach (var item in column.Columns)
{
SetCellColumnDefinition(sbStr, item, ref index);
}
}
else
{
if (index > )
{
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 = ; i <= LevelDepth; i++)
{
if (i > )
{
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 = ;
foreach (var item in column.Columns)
{
SetColumnDefinition(sbHeaderStr, item, ref index);
}
sbHeaderStr.AppendLine("</Grid.ColumnDefinitions>"); int columnOffset = totalcolumnCount * - ; sbHeaderStr.AppendLine(CreateDataGridTemplateColumnHeaderContent(String.IsNullOrWhiteSpace(column.ExtendName) ? column.Name : column.ExtendName, -, -, -, columnOffset)); sbHeaderStr.AppendLine(String.Format("<Rectangle Fill=\"#FFC9CACA\" VerticalAlignment=\"Stretch\" Height=\"1\" Grid.Row=\"1\" Grid.ColumnSpan=\"{0}\" />", columnOffset)); index = ;
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 = ;
foreach (var item in column.Columns)
{
SetCellColumnDefinition(sbCellTempStr, item, ref index);
}
sbCellTempStr.AppendLine("</Grid.ColumnDefinitions>");
index = ;
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 > )
{
sbStr.AppendFormat(" Grid.Row=\"{0}\"", row);
}
if (rowSpan > )
{
sbStr.AppendFormat(" Grid.RowSpan=\"{0}\"", rowSpan);
}
if (column > )
{
sbStr.AppendFormat(" Grid.Column=\"{0}\"", column);
}
if (columnSpan > )
{
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, -, -, -, -));
//动态构建标题样式 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
}