zoukankan      html  css  js  c++  java
  • 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<DDL>)[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 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 });
                }
            }
        }
    }
  • 相关阅读:
    理解Java虚拟机——Java内存模型管理
    Java 使用fastjson 将 json字符串写到文件中去
    java 如何调用 linux or mac 命令行
    MacOS 编译 openjdk8 并导入 Clion 调试
    linux ls 命令超级详解
    小 Q 与树 (点分治)
    mysql 索引策略
    java中serialVersionUID作用
    通过源码分析Spring Security用户认证流程
    使用PowerMockRunner和Mockito编写单元测试用例详解
  • 原文地址:https://www.cnblogs.com/T-ARF/p/12182407.html
Copyright © 2011-2022 走看看