• 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, 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接口

        /// <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 > 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
        }
  • 相关阅读:
    Flush the AOS cache from code
    EntityConnectionStringBuilder 构造EF连接字符串
    AX中文转拼音
    AX2012 AOT中Web部署显示二级以上菜单
    clearCompanyCache
    AX2009 打印到PDF优化
    AX ODBC读取其他SQL数据库服务器数据
    AX2009报表打印固定长度Barcode条码
    Create Product Variant
    Rename AOT Object
  • 原文地址:https://www.cnblogs.com/xhh-lite/p/6841477.html
Copyright © 2020-2023  润新知