zoukankan      html  css  js  c++  java
  • 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
        }
  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/xhh-lite/p/6841477.html
Copyright © 2011-2022 走看看