wpf datagrid显示列

这个会生成3列,

List<Person> list = new List<Person>();

            list.Add(new Person { Name = "张三", Age = 22, Address = "广东省廉江市车板镇大坝村" });
            list.Add(new Person { Name = "李四", Age = 23, Address = "江西省景德镇市市辖区" });
            list.Add(new Person { Name = "王五", Age = 24, Address = "上海市虹口区" });

这个也会有三列,怎么解决?

            datagrid.ItemsSource = list;             <DataGrid.Columns>
                <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
                <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
                <DataGridTextColumn Header="地址" Binding="{Binding Address}" />
            </DataGrid.Columns>

从你提供的代码来看,DataGrid的列似乎被定义了两次:一次是通过绑定ItemsSource属性到一个包含Person对象的列表,另一次是在XAML中静态定义了三个DataGridTextColumn列。通常情况下,如果你没有设置AutoGenerateColumns="True"DataGrid应该不会自动生成列。不过,如果你发现实际运行的应用中列被重复添加了,这通常是因为AutoGenerateColumns属性默认为True,导致DataGrid既生成了基于数据源的列,也生成了XAML中定义的列。

要解决这个问题,确保AutoGenerateColumns属性被明确设置为False,以便DataGrid只使用XAML中定义的列:

<DataGrid x:Name="datagrid" 
          SelectionMode="Extended"
          IsReadOnly="True" 
          HorizontalAlignment="Left"
          AutoGenerateColumns="False"
          SelectionChanged="datagrid_Selected">
    <DataGrid.Columns>
        <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
        <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
        <DataGridTextColumn Header="地址" Binding="{Binding Address}" />
    </DataGrid.Columns>
</DataGrid>

在这个修正中,添加了AutoGenerateColumns="False"DataGrid的属性中,这将阻止DataGrid根据数据源自动创建列。这样,DataGrid将只显示在<DataGrid.Columns>节点中定义的列。

如果不适用这个AutoGenerateColumns=“False”,这段代码怎么修改比较好?


如果您不想使用 AutoGenerateColumns="False",那么您应该完全依赖于 DataGrid 自动从数据源生成列的功能,而不在 XAML 中显式声明列。

要做到这一点,您应该从 XAML 中移除 <DataGrid.Columns> 节点,因为 DataGrid 将根据绑定到 ItemsSource 的数据对象的公共属性自动为您生成列。这就要求您的数据对象(在此例中为 Person 类)的每个公共属性都将成为 DataGrid 的一个列。

以下是更新后的 XAML 示例,其中移除了列的静态定义:

<DataGrid x:Name="datagrid" 
          SelectionMode="Extended"
          IsReadOnly="True" 
          HorizontalAlignment="Left"
          SelectionChanged="datagrid_Selected">
    <!-- DataGrid.Columns section is removed to rely on auto-generated columns -->
</DataGrid>

在后台代码中,您保留对 ItemsSource 的设置:

public MainWindow()
{
    InitializeComponent();

    List<Person> list = new List<Person>
    {
        new Person { Name = "张三", Age = 22, Address = "广东省廉江市车板镇大坝村" },
        new Person { Name = "李四", Age = 23, Address = "江西省景德镇市市辖区" },
        new Person { Name = "王五", Age = 24, Address = "上海市虹口区" }
    };

    datagrid.ItemsSource = list;
}

这样做之后,当您运行应用程序,DataGrid 将仅显示来自 Person 对象列表的属性为列,而不会有任何在 XAML 中静态定义的列。这种方法的优点是简化了 XAML,使得任何对数据对象(如 Person 类)的更改都会自动反映在 DataGrid 的列上。缺点是您将失去在 XAML 中直接定义列时能够进行的细粒度控制,比如设置列宽和格式化。如果您需要这些控制,可以通过编程方式在后台代码中配置自动生成的列,或者简单地保留 AutoGenerateColumns="False" 并在 XAML 中显式定义您的列。

列显示的是英文,如果我想显示中文,或者其他语言怎么办?


如果您希望DataGrid中的列标题显示为中文或其他语言,而不是数据源中属性的名称,您可以在绑定时为每个列设置Header属性。如果您不使用AutoGenerateColumns="False",则无法在XAML中预先设置列标题,因为列是自动生成的。不过,您可以通过在代码后台中处理DataGridAutoGeneratingColumn事件来改变列标题。

以下是如何在后台代码中处理AutoGeneratingColumn事件以设置列标题为中文的示例:

在XAML中,为DataGrid添加AutoGeneratingColumn事件处理器:

<DataGrid x:Name="datagrid" 
          SelectionMode="Extended"
          IsReadOnly="True" 
          HorizontalAlignment="Left"
          SelectionChanged="datagrid_Selected"
          AutoGeneratingColumn="datagrid_AutoGeneratingColumn">
</DataGrid>

在后台代码(C#)中,添加datagrid_AutoGeneratingColumn事件处理器的实现:

private void datagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    // 检查正在生成的列并设置中文标题
    if (e.PropertyName == "Name")
    {
        e.Column.Header = "姓名";
    }
    else if (e.PropertyName == "Age")
    {
        e.Column.Header = "年龄";
    }
    else if (e.PropertyName == "Address")
    {
        e.Column.Header = "地址";
    }
    // 对于其他语言,也可以在此设置相应的标题
    // 例如,如果您需要日语,可以设置为 e.Column.Header = "名前"; 等等
}

这段代码会检查每一个自动生成的列,并将其Header属性设置为您提供的中文字符串。这样,即使列是根据数据源的属性自动生成的,您仍然可以控制它们的显示标题。

这种方法提供了在运行时根据列的属性名来自定义列标题的灵活性,这样即使您使用的是自动生成列的功能,也可以实现多语言支持。

还有其他方法吗?


如果您希望在 DataGrid 中显示中文列名,并且不使用 AutoGenerateColumns="False" 属性,您还可以通过绑定到一个具有中文属性名称的数据源来解决。这涉及到使用数据转换器或创建一个包含中文属性名的新数据类型。但是,这通常不是推荐的方法,因为它可能涉及到重构您的数据模型以适应UI显示的需求,这并不是数据模型的最佳实践。

除了直接在 AutoGeneratingColumn 事件中设置列头之外,还有一些其他策略可以考虑:

使用资源文件进行国际化

如果您的应用程序需要支持多种语言,则可以使用资源文件来实现国际化:

  1. 为每种语言创建一个资源文件(例如,Resources.zh-CHS.resx 用于简体中文,Resources.en-US.resx 用于英文)。
  2. 在资源文件中为每个列名定义一个资源键值对。
  3. AutoGeneratingColumn 事件中使用资源文件中的字符串替换默认列名。
private void datagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    e.Column.Header = Properties.Resources.ResourceManager.GetString(e.PropertyName);
}

使用 DisplayName 属性

如果您的数据模型允许,您可以在模型属性上使用 DisplayName 属性来指定列名。DataGrid 并不直接使用这个属性,但是您可以在 AutoGeneratingColumn 事件中使用它来获取列名。

[DisplayName("姓名")]
public string Name { get; set; }

然后,在 AutoGeneratingColumn 事件中读取这个属性:

private void datagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var displayNameAttribute = e.PropertyDescriptor.Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute;
    if (displayNameAttribute != null)
    {
        e.Column.Header = displayNameAttribute.DisplayName;
    }
}

显式声明列的绑定和列头

这不是自动化的方法,但它允许你在 XAML 中完全控制列的创建,包括列头和绑定。

在这种情况下,您会将 AutoGenerateColumns 设置为 False 并且显式声明每列,就像在之前的例子中一样。如果数据源的属性名称改变,您也需要更新 XAML 代码。

总结

AutoGeneratingColumn 事件处理器是处理自动生成列并为其指定自定义列头的标准方法。使用资源文件进行国际化或在数据模型中使用 DisplayName 属性可以提供额外的灵活性和多语言支持。在多种情况下,选择最佳方法取决于您应用程序的具体需求和数据模型的复杂性。

  • 38
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值