如何自定义数据网格的列(并仅显示几个字段)



所以我是第一次使用 WPF(实际上是整个 C#(,我正在努力解决我想要自定义的Datagrid

public MainWindow()
{
InitializeComponent();
animalsGrid.ItemsSource = ViewModel.getAnimalsList();
ScrollPane.Content = animalsGrid;
}

这是Animal类:

public class Animal() {
string name;
string race;
string habitat;
string age;
/*
* constructor, methods etc
*/
}

如您所见,我正在用具有一堆规范(字段(的动物列表填充我的Datagrid。用户不需要所有这些规范。如何确保Datagrid中仅显示某些字段?即只有namerace

这里有几个选项,如果在 xaml 中将自动生成的列定义为 true,则只应将公共属性创建为列。此外,您还可以编写一个行为,在此处创建的列之前检查内容,您甚至可以为此创建自定义属性。综上所述,最常见的入门方法是将自动生成的列设置为 false,并创建要在 xaml 中显示的所有列,并将项的属性显式绑定到列。

属性和属性的更新

public class Animal() {
string name;

[Browsable(false)]
public string Name ...
}

如果使用自动生成的列,此属性将阻止催化将此属性呈现为列。当然在这里没有放一个完整的例子

行为更新

如果您想为网格使用自定义行为,您可以执行类似操作

namespace yourApp.Infrastructure
{
public class HideAutogeneratedColumsBehaviour : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGridOnAutoGeneratingColumn);
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.AutoGeneratingColumn -= new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGridOnAutoGeneratingColumn);
}
private static void DataGridOnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyDescriptor is PropertyDescriptor propDesc)
{
// DO things 
}
}
}
}

而不是通过将命名空间添加到 Window 类在 XAML 中使用它

xmlns:infrastructure="clr-namespace:yourApp.Infrastructure"

在数据网格上,请注意这并不完整,您还需要为交互添加命名空间。

<DataGrid AutoGenerateColumns="True">
<i:Interaction.Behaviors>
<infrastructure:HideAutogeneratedColumsBehaviour />
</i:Interaction.Behaviors>
</DataGrid>

如果您想使用自定义属性来检查您的行为,那么您可以做类似的事情。

namespace yourApp.Infrastructure
{
[AttributeUsage(AttributeTargets.Property)]
public class YourCustomAttribute : Attribute
{
private string attributeValue;

public YourCustomAttribute(string value)
{
attributeValue = value;
}
public string AttributeValue{ get => name; }
}
}

并在属性的代码中使用它

[YourCustomAttribute("foo")]
public string MyProperty { get => myProperty; set { myProperty = value; } } 

再次只是一个例子,然后检查您的行为

if (e.PropertyDescriptor is PropertyDescriptor propDesc)
{
foreach (Attribute att in propDesc.Attributes)
{
if(att is YourCustomAttrbute customAttr)
{
// do something
}
}
}

所以我希望你能从我的更新中得到一些想法,如何自定义你的列。

我建议添加一个自定义属性来指示要隐藏的列:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace CustomizeDataGrid
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
IList<Animal> animals = new List<Animal>() { new Animal("Tiget", "race1", "habitat1", "12"), new Animal("Cat", "race2", "habitat2", "23"), };
Animals = CollectionViewSource.GetDefaultView(animals);
InitializeComponent();
dataGrid1.ItemsSource = Animals;
}
private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyDescriptor is PropertyDescriptor prop && prop.Attributes.OfType<HiddenAttribute>().Any())
{
e.Cancel = true;                
}
}
public ICollectionView Animals { get; set; }
}

public class Animal
{
public Animal(string name, string race, string habitat, string age)
{
Name = name;
Race = race;
Habitat = habitat;
Age = age;
}
public string Name { get; set; }
[Hidden]
public string Race { get; set; }
public string Habitat { get; set; }
public string Age { get; set; }
}
public class HiddenAttribute : Attribute
{       
}
}

XAML:

DataGrid x:Name="dataGrid1" AutoGenerateColumns="True" AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn"/>

最新更新