美文网首页
WPF-动态生成DataGrid

WPF-动态生成DataGrid

作者: 写前端的大叔 | 来源:发表于2020-03-22 13:55 被阅读0次

    在封装自定义组件的时候,看到很多类似表格的控件,表格中的数据都不是固定的,每个表格的表条和内容都不一样,如果直接在xaml文件中定义DataGrid的话,就显得很麻烦了,可以将期封装成一个动态生成的DataGrid,只需按照一定规则的数据格式,就可以生成表格。如下所示为封装后的一个动态表格:

    动态表格.png

    1.数据格式

    首先来定义一个数据格式,数据格式相对比较简单,只需一个表头字段、内容字段、列宽字段。如下所示:

     public class GridInfo {
            public string name { get; set; }
            public string value { get; set; }
            public int column { get; set; }
        }
    

    2.创建DataGrid

    首先创建一个UserControl,然后在里面放入一个DataGrid,并设置样式,如下所示:

    <UserControl x:Class="WpfApp1.UCInfoGridColumn"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApp1"
                 DataContext="{Binding RelativeSource={RelativeSource Self}}"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <UserControl.Resources>
            <Style TargetType="DataGrid">
                <!--网格线颜色-->
                <Setter Property="CanUserResizeColumns" Value="false"/>
                <Setter Property="BorderBrush" Value="#0668BA" />
                <Setter Property="HorizontalGridLinesBrush">
                    <Setter.Value>
                        <SolidColorBrush Color="#0668BA"/>
                    </Setter.Value>
                </Setter>
                <Setter Property="VerticalGridLinesBrush">
                    <Setter.Value>
                        <SolidColorBrush Color="#0668BA"/>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style TargetType="DataGridColumnHeader">
                <Setter Property="SnapsToDevicePixels" Value="True" />
                <Setter Property="Background" Value="White" />
                <Setter Property="FontSize" Value="14" />
                <Setter Property="FontWeight" Value="Bold" />
                <Setter Property="Cursor" Value="Hand" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGridColumnHeader">
                            <Border x:Name="BackgroundBorder" BorderThickness="0,1,0,1" 
                                 BorderBrush="#0668BA" 
                                  Width="Auto">
                                <Grid >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
                                    <ContentPresenter  Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                    <Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill"  Grid.Column="2" Width="8" Height="6" Fill="White" Margin="0,0,50,0" 
                                VerticalAlignment="Center" RenderTransformOrigin="1,1" />
                                    <Rectangle Width="1" Fill="#0668BA" HorizontalAlignment="Right" Grid.ColumnSpan="1" />
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="Height" Value="40"/>
            </Style>
            <!--行样式触发-->
            <!--背景色改变必须先设置cellStyle 因为cellStyle会覆盖rowStyle样式-->
            <Style  TargetType="DataGridRow">
                <Setter Property="Background" Value="#344488" />
                <Setter Property="Height" Value="40"/>
                <Setter Property="Foreground" Value="White" />
                <Style.Triggers>
                    <!--隔行换色-->
                    <Trigger Property="AlternationIndex" Value="0" >
                        <Setter Property="Background" Value="#344488" />
                    </Trigger>
                    <Trigger Property="AlternationIndex" Value="1" >
                        <Setter Property="Background" Value="#344488" />
                    </Trigger>
    
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#344488"/>
                    </Trigger>
    
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
    
            <!--单元格样式触发-->
            <Style TargetType="DataGridCell">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGridCell">
                            <TextBlock TextAlignment="Center" VerticalAlignment="Center"  >
                               <ContentPresenter />
                            </TextBlock>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
            
        </UserControl.Resources>
        <Border BorderBrush="#0668BA" BorderThickness="1" CornerRadius="3">
            <DataGrid x:Name="dataGrid" HorizontalScrollBarVisibility="Hidden" Foreground="White" Background="#102371"></DataGrid> 
        </Border>
    </UserControl>
    
    

    3.动态生成表格

    .cs文件中,添加一个方法,用于传递数据,并根据数据动态生成表格,如下所示:

    public void loadData(ObservableCollection<GridInfo> list) {
                if (list == null) {
                    return;
                }
                //计算出每一列的宽度
                double width = this.ActualWidth / list.Count;
                dataGrid.Columns.Clear();//每次清空列集合
                for (int i = 0; i < list.Count; i++)
                {
                    GridInfo gridInfo = list[i];
                    DataGridTextColumn textBoxColumn = new DataGridTextColumn();
                    textBoxColumn.Header = gridInfo.name;
    
                     //定义每一列的宽度相同
                     //textBoxColumn.Width = new DataGridLength(dataGrid.ActualWidth, DataGridLengthUnitType.Star);
                    textBoxColumn.Width = width * gridInfo.column;//定义每一列的最小宽度
                    Binding binding = new Binding("value");//设置每一列的binding
                    //binding.Path = new PropertyPath("name");
                    binding.Mode = BindingMode.OneWay;
                    textBoxColumn.Binding = binding;
                    dataGrid.Columns.Add(textBoxColumn);//将列添加到集合中
                }
                dataGrid.ItemsSource = list;
                dataGrid.AutoGenerateColumns = false;//禁止自动添加列
                dataGrid.CanUserAddRows = false;//禁止自动添加行
                dataGrid.RowHeaderWidth = 0;//去除第一列多余的空白
            }
    

    引入动态表格

    创建好表格后,然后再需要地方通过如下方式进行引入:

    <local:UCInfoGridColumn  Margin="101,54,0,0" VerticalAlignment="Top" Width="549" x:Name="infoGrid"/>
    

    然后在loaded事件中加入测试数据,来调用loadData方法动态添加表格信息,如下所示:

     private void Page_Loaded(object sender, RoutedEventArgs e)
            {
    
                ObservableCollection<GridInfo> list = new ObservableCollection<GridInfo>();
                for (int i = 0; i < 3; i++)
                {
                    GridInfo column = new GridInfo();
                    column.name = "标题" + i;
                    column.value = "内容" + i;
                    column.column = 1;
                    list.Add(column);
                }
                infoGrid.loadData(list);
            }
    

    按以下步骤来做,就可以快速的创建一个自定义的动态表格了。
    个人博客

    相关文章

      网友评论

          本文标题:WPF-动态生成DataGrid

          本文链接:https://www.haomeiwen.com/subject/lwamyhtx.html