WPF根据xml配置文件加载DataGrid列

  实习那会儿,公司里WinFrom的数据表格也是根据xml配置文件动态生成列的,只怪当时没有好好看源码,后来上网学习里一些有关xml才下手搞一个基于wpf 、c# 动态生成DataGrid列。

  想要通过代码生成数据表格列还是得需要了解DataGrid的Columns结构,至于使用xml配置文件可以看我之前的:c#通过model生成/读取xml文件

简单看一下数据表格列的xaml文本显示的结构:

<DataGrid x:Name="DataGridContent" LoadingRow="DGBuilding_LoadingRow">
    <DataGrid.Columns>
        <DataGridTextColumn  Header="1" Width="150" Binding="{Binding column1}"></DataGridTextColumn>
        <DataGridTextColumn Header="2" Width="170" Binding="{Binding column2}"></DataGridTextColumn>
        <DataGridTextColumn Header="3" Width="120" Binding="{Binding column3}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

可以看到DataGrid下有<DataGrid.Columns>再下一层就是具体的列了。

现在开始简单搭建页面:

<Window x:Class="Demo_XMLLoadDataGridColumn.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Demo_XMLLoadDataGridColumn"
        mc:Ignorable="d"
        Title="XML配置文件加载数据表格列" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="376*"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Auto" x:Name="StackPanelControl">
            <Button Width="100" Height="20" Content="Column1" x:Name="Column1" Click="Column1_Click" Margin="10"/>
            <Button Width="100" Height="20" Content="Column2" x:Name="Column2" Click="Column2_Click" Margin="10"/>
            <Button Width="100" Height="20" Content="清除" x:Name="Eliminate" Click="Eliminate_Click" Margin="10"/>
        </StackPanel>
        <Grid Grid.Row="1">
            <DataGrid x:Name="DataGridContent" LoadingRow="DGBuilding_LoadingRow">
                
            </DataGrid>
        </Grid>
    </Grid>
</Window>

效果图:

再写一个Model用来生成xml配置文件和用来加载数据表格列的。

public class DataGridColumn
{
    private string _templateType = string.Empty;
    private string _header = string.Empty;
    private string _binding = string.Empty;
    private string _width = string.Empty;
    /// <summary>
    /// 数据模板
    /// </summary>
    public string TemplateType
    {
        get { return _templateType; }
        set { _templateType = value; }
    }
    /// <summary>
    /// 列名字
    /// </summary>
    public string Header
    {
        get { return _header; }
        set { _header = value; }
    }
    /// <summary>
    /// 绑定
    /// </summary>
    public string Binding
    {
        get { return _binding; }
        set { _binding = value; }
    }
    /// <summary>
    /// 列长度
    /// </summary>
    public string Width
    {
        get { return _width; }
        set { _width = value; }
    }
}

在页面的构造函数里写生成xml配置文件的代码:

public MainWindow()
{
    InitializeComponent();

    Directory.CreateDirectory("Xml");//在bin> debug 文件夹下创建名为Xml的文件夹,除非已经存在。
    List<DataGridColumn> lstDataGridColumn = new List<DataGridColumn>();
    lstDataGridColumn.Add(new DataGridColumn() { Header = "学生姓名", Binding = "Student" ,Width = "100"});
    lstDataGridColumn.Add(new DataGridColumn() { Header = "性别", Binding = "Sex" ,Width = "100"});
    lstDataGridColumn.Add(new DataGridColumn() { Header = "班级", Binding = "Class" ,Width = "100"});
    SetXML("Column1", lstDataGridColumn);
    List<DataGridColumn> lstDataGridColumn2 = new List<DataGridColumn>();
    lstDataGridColumn2.Add(new DataGridColumn() { TemplateType = "DTTextBlock", Header = "序号", Width = "50" });
    lstDataGridColumn2.Add(new DataGridColumn() { Header = "班级", Width = "50" });
    lstDataGridColumn2.Add(new DataGridColumn() { Header = "类别", Width = "50" });
    SetXML("Column2",lstDataGridColumn2);
}
//初始化XML配置文件
void SetXML(string strXMLName, List<DataGridColumn> lstDataGridColumn)
{
    using (Stream stream = File.Open(string.Format("Xml/{0}.xml", strXMLName), FileMode.Create))//在此路径创建一个新xml文件,如果已存在则覆盖
    {
        var serializer = new XmlSerializer(lstDataGridColumn.GetType());//这个是关键。根据model的属性创建xml节点
        serializer.Serialize(stream, lstDataGridColumn);
    }
}

关于DataGrid的数据模板,我是在资源字典里写好的,然后再根据key加载到DataGrid里,首先创建一个资源字典:

然后再里面写数据模板。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Demo_XMLLoadDataGridColumn">
    <DataTemplate x:Key="DTTextBlock">
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}, Path=Header}" 
                   HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10,0,0,0"></TextBlock>
    </DataTemplate>
</ResourceDictionary>

然后记得在主程序的App.xaml写引用此资源字典。

<Application x:Class="Demo_XMLLoadDataGridColumn.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Demo_XMLLoadDataGridColumn"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary Source="DataGridColumnBase.xaml"/><!--资源字典-->
    </Application.Resources>
</Application>

先运行一下程序,让她跑一下生成xml配置文件的代码看看,发现已经成功生成xml配置文件了:

然后再给Column1、Column2和清除按钮添加点击事件,读取配置文件然后把配置文件里的数据给到之前新建的model:DataGridColumn,然后再做代码添加列的操作,详细如下:

private void Column1_Click(object sender, RoutedEventArgs e)
{
    SetXMLDataGridColumns("Column1");
}

private void Column2_Click(object sender, RoutedEventArgs e)
{
    SetXMLDataGridColumns("Column2");
}
private void Eliminate_Click(object sender, RoutedEventArgs e)
{
    DataGridContent.Items.Clear();//移除所有数据
    DataGridContent.Columns.Clear();//清除表格的列
}
void SetXMLDataGridColumns(string strDataGridColumnName)
{
    DataGridContent.Columns.Clear();//清除表格的列
    List<DataGridColumn> lstDataGridColumns = new List<DataGridColumn>();
    Directory.CreateDirectory("Xml");
    //确定指定的文件是否存在
    if (File.Exists(string.Format("Xml/{0}.xml", strDataGridColumnName)))
    {
        using (var stream = File.OpenRead(string.Format("Xml/{0}.xml", strDataGridColumnName)))
        {
            var serializer = new XmlSerializer(lstDataGridColumns.GetType());
            lstDataGridColumns = serializer.Deserialize(stream) as List<DataGridColumn>;
        }
        foreach (DataGridColumn item in lstDataGridColumns)
        {
            Binding binding = new Binding();
            if (!string.IsNullOrWhiteSpace(item.Binding))
                binding.Path = new PropertyPath(item.Binding);
            if (string.IsNullOrWhiteSpace(item.TemplateType))
            {
                DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
                dataGridTextColumn.Header = item.Header;
                dataGridTextColumn.Width = new DataGridLength(Convert.ToDouble(item.Width));
                if (!string.IsNullOrWhiteSpace(item.Binding))
                    dataGridTextColumn.Binding = new Binding(item.Binding);
                DataGridContent.Columns.Add(dataGridTextColumn);
            }
            else
            {
                DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();
                dataGridTemplateColumn.Header = item.Header;
                dataGridTemplateColumn.CellTemplate = (DataTemplate)DataGridContent.FindResource(item.TemplateType);//这里根据xml的数据值找到对应的资源文件里的key值的数据模板
                DataGridContent.Columns.Add(dataGridTemplateColumn);
            }
        }
    }
    else
        MessageBox.Show("不存在配置文件!");
}

给数据表格添加行加载事件:LoadingRow;

private void DGBuilding_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = e.Row.GetIndex() + 1;
}

这个是用于数据模板“序号“需要使用到的。

运行程序看一下效果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值