WPF DataGrid表头合并且动态添加列

DataGrid要实现表头合并的效果。首先使用DataGridTemplate作为列。同时修改HeaderTemplate。但是效果没有那么好且有其他问题。

真正的修改的地方是修改HeaderStyle的DataGridColumnHeader。

内容模板则是修改CellTemplate就好了

如果要是同态添加列则是需要使用继承DataGridTemplate的类。

重写GenerateElement方法,并设置好内容模板的数据源。

所以大部分的内容都是C#代码,Xaml的部分则就是datatemplate的部分。

xaml代码

 <Window.Resources>
        <local:SetWidthConvert x:Key="SetWidthConvert"/>
        <DataTemplate x:Key="CDT">
            <ItemsControl x:Name="ic1"  ItemsSource="{Binding List[0].TestType}" Margin="-1">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0,0,1,0" BorderBrush="Black"  MinWidth="30"   >
                            <Border.Width>
                                <MultiBinding Converter="{StaticResource SetWidthConvert}" >
                                    <Binding  RelativeSource="{RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ItemsControl}" Path="ActualWidth"/>
                                    <Binding  RelativeSource="{RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ItemsControl}" Path="ItemsSource.Count"/>
                                </MultiBinding>
                            </Border.Width>
                            <TextBlock   HorizontalAlignment="Center" Text="{Binding  }"/>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
        <ControlTemplate x:Key="CT1" TargetType="DataGridColumnHeader">
            <Border BorderThickness="0,0,1,0" BorderBrush="Black" >
                <Grid MinHeight="120" x:Name="g1" Margin="-1"  DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=DataGridColumnHeader},Path=Column.ItemSource}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding  RequestName}"  HorizontalAlignment="Center"   VerticalAlignment="Center"/>
                    <Border Grid.Row="1"  BorderBrush="Black" BorderThickness="0,1,0,0"    >
                        <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext[0].RequestNumList}" x:Name="ic"  >
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border BorderThickness="0,0,1,0"  BorderBrush="Black"  >
                                        <Border.Width>
                                            <MultiBinding Converter="{StaticResource SetWidthConvert}" >
                                                <Binding  RelativeSource="{RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ItemsControl}" Path="ActualWidth"/>
                                                <Binding  RelativeSource="{RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ItemsControl}" Path="ItemsSource.Count"/>
                                            </MultiBinding>
                                        </Border.Width>
                                        <TextBlock  VerticalAlignment="Center"  HorizontalAlignment="Center" Text="{Binding   }" FontSize="15" />
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Border>
                </Grid>
            </Border>
        </ControlTemplate>
        <Style x:Key="s1" TargetType="DataGridColumnHeader">
            <Setter Property="Template" Value="{StaticResource CT1 }"/>
        </Style>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="DG" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="课程名称"    Binding="{Binding  SchoolName}" Width="150"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

C#代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace 表头合并
{
    class SetWidthConvert : IMultiValueConverter, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnChanged(PropertyChangedEventArgs args) => this.PropertyChanged?.Invoke(this, args);

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {

            var w1 = (double)values[0];
            var w2 = System.Convert.ToDouble(values[1]);
            return w1 / w2;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class DataNewColumn : DataGridTemplateColumn
    {
        public static readonly DependencyProperty ItemSourceProperty = DependencyProperty.Register("ItemSource", typeof(object), typeof(DataNewColumn));
        public object ItemSource
        {
            get
            {
                return (object)GetValue(ItemSourceProperty);

            }
            set
            {
                SetValue(ItemSourceProperty, value);
            }
        }

        protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            cell.BorderThickness = new Thickness(0);
            var d = cell.Column as DataGridTemplateColumn;
            var p = d.CellTemplate;
            if (ItemSource != null)
            {
                var ds = p.LoadContent() as ItemsControl;
                ds.SetValue(ItemsControl.ItemsSourceProperty, (ItemSource as List<DDL>)[0].TestType);
                return ds;
            }
            return null;

        }
    }
    public class DataList
    {
        public string SchoolName { get; set; }
        public List<DDL> List { get; set; }
    }
    public class DDL
    {
        public string RequestName { get; set; }
        public List<int> RequestNumList { get; set; }
        public List<string> TestType { get; set; }
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        List<DataList> GetDataLists = new List<DataList>();
        public MainWindow()
        {
            InitializeComponent();

            Init();
            Create();
        }
        private void Create()
        {
            this.DG.ItemsSource = GetDataLists;
            for (var i = 0; i < GetDataLists.Count; i++)
                Add(i);
        }

        private void Add(int i)
        {
            var clm = this.DG.Columns;
            var b = new DataNewColumn();
            b.ItemSource = GetDataLists[i].List;
            b.CellTemplate = this.FindResource("CDT") as DataTemplate;
            b.HeaderStyle = this.FindResource("s1") as Style;
            clm.Add(b);
        }

        private void Init()
        {
            Random random = new Random();
            for (var O = 0; O < 5; O++)
            {
                List<string> testtpyelist = new List<string>();
                List<int> requestnumlist = new List<int>();
                string requestname = "要求" + O.ToString();
                var d = random.Next(1, 10);
                for (var p = 0; p < d; p++)
                {
                    requestnumlist.Add(p);
                    testtpyelist.Add((p % 2 == 0) ? " " : "低");
                }
                var k = new DDL();
                k.TestType = testtpyelist;
                k.RequestNumList = requestnumlist;
                k.RequestName = requestname;

                var l = "大学  NO." + O.ToString();
                var t = new List<DDL>();
                t.Add(k);
                GetDataLists.Add(new DataList() { SchoolName = l, List = t });
            }
        }
    }
}

原文地址:https://www.cnblogs.com/T-ARF/p/12182407.html

时间: 2024-08-29 11:42:43

WPF DataGrid表头合并且动态添加列的相关文章

EasyUI datagrid动态添加列

任务描述:根据用户选择时间段,生成列数据,如图 一.先定义好datagrid固定的数据列 <script type="text/javascript"> $(document).ready(function () { $("#td_Radio").datagrid({ striped: true, border: true, iconCls: 'icon-edit', //图标 singleSelect: true, autoRowHeight: tru

WPF Toolkit Chart--动态换列

效果: <Window x:Class="切换显示曲线.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width=&qu

Wpf DataGrid动态添加列,行数据(二)

这是第二中方法,可直接绑定,我这里只是做出了一种思路,并不是最完美. 这里注意一下,因为我里面引用了MVVMLight,所以可能代码不是复制过去就能用了的. 样式也是,所以复制过去看不是我贴出来的界面这也不奇怪.代码: <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions

动态添加列之后,铵钮事件怎样写?

有网友来问题,“想通过后台代码给gridview绑定数据,然后在最后一列添加Button,点击按钮后获得所在行的某个数据, 在网上找到了动态生成按钮的程序,但是不知道怎么给这个按钮添加一个Click事件” : 网友也许是看了Insus.NET这篇<动态为GridView控件创建列>http://www.cnblogs.com/insus/archive/2011/06/10/2077538.html .此篇中只有演示动态添加一列,此列是一个图片铵钮. 想实现GridView中任何一行或是任何一

easyui dataGrid 动态添加列

其实很简单.新手创作,不好勿喷.jsp页面: 1 <script> 2 $(function () { 3 4 $.getJSON('${pageContext.request.contextPath}/resources/json/datagrid_data.json',function(result){ 5 var columns=new Array(); 6 $.each(result.headers[0], function(i, field){ 7 var column={}; 8

GridView动态添加列并判断绑定数据DataTable的列类型控制展示内容

此篇随笔是2013年根据项目需求开发记录的,不一定符合大众口味,只需了解开发思路,毕竟解决方案多种多样. 下面简单说说需求点吧: (1)通过下拉列表可以选择一个DataSet(数据集),一个DataSet存在可以互相关联的多个DataTable(数据表格),DataTable数据来源于数据库视图:SQL语句关联比较复杂 (2)一个DataTable(数据表格)存在多个可供选择查询显示的Column(列),支持动态组合 (3)Column(列)同时支持作为查询条件进行并运算 先看效果吧,免得待会看

extjs动态添加列

可以根据日期,动态的插入一列 controller层: 1 StdDayWordQuery:function(btn,event){ 2 var form=Ext.getCmp('queryFormSDW'); 3 paramsForDayWord=Ext.encode(form.getForm().getValues()); 4 Ext.Ajax.request({ 5 url:'getDailyWordNum.action', 6 headers: { 7 'Content-Type': '

WPF DataGrid中鼠标双击某一列,弹出窗体作为(增加、修改、详细)按钮的快捷键。

跟触发器行为有关,什么是触发器什么是行为,我并不能看懂.在此先强行记忆,后知后觉,再回来理解.先能把手里的活做出来,这能让你暂时不被开除.实话实说.——一个菜农的自述. 这个时候就会有一些爱教的,好为人师,跳出来一副指点迷津的样子,打着授之予渔的幌子,开始跟你吹牛逼,开始说一些自己都不J8明白的东西.我只是问一个简单的问题,你直接告诉我1+1=2就可以了.你妈逼,用你告诉我,1+1在真正的时候用不上么?用你告诉我这么写不好,不高端,你要是不屑写这种新手理解的东西,那你就别理我,你可以不善良,你别

DataSet 动态添加列

public DataSet GetNewId(List<string> IdArr) { DataSet ds = new DataSet(); DataTable newtb = new DataTable(); DataColumn column = new DataColumn("cnt", typeof(string));//新增列 newtb.Columns.Add(column); for (int i = 0; i < IdArr.Count; i++