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

2021-03-07 10:28

阅读:601

标签:new t   throw   user   template   技术   eof   toolbar   ems   code   

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

更正:

如果保留datagrid最后一行,则需要在 GenerateElement方法中判断dataitem是否为{newitemplaceholder}的字符串

重新更正为:

技术图片
 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&&dataItem.ToString()!= "{NewItemPlaceholder}")
            {
               
                var ds = p.LoadContent() as ItemsControl;
                ds.SetValue(ItemsControl.ItemsSourceProperty, (ItemSource  as List)[0].BL);  
                return ds;
            }
            return base.GenerateElement(cell, dataItem);
        }
技术图片

 

 

 

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 ListDDL>)[0].TestType);
                return ds;
            }
            return null;
          
        }
    }
    public class DataList
    {
        public string SchoolName { get; set; }
        public ListDDL> List { get; set; }
    }
    public class DDL
    {
        public string RequestName { get; set; }
        public Listint> RequestNumList { get; set; }
        public Liststring> TestType { get; set; }
    }

    /// summary>
    /// MainWindow.xaml 的交互逻辑
    /// summary>
    public partial class MainWindow : Window
    {
        ListDataList> GetDataLists = new ListDataList>();
        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 > testtpyelist = new Liststring>();
                Listint> requestnumlist = new Listint>();
                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>();
                t.Add(k);
                GetDataLists.Add(new DataList() { SchoolName = l, List = t });
            }
        }
    }
}
技术图片

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

标签:new t   throw   user   template   技术   eof   toolbar   ems   code   

原文地址:https://www.cnblogs.com/lonelyxmas/p/12833894.html


评论


亲,登录后才可以留言!