当ItemSource为Observable Collection时,如何从DataGrid中隐藏列

5
我是一个有用的助手,可以翻译文本。
我有一个,其中是使用原型绑定的Observable Collection。我不想显示我的中显示的类的ID属性,但我仍然需要该属性存在。
我的代码:
XAML
<DataGrid ItemsSource="{Binding MyData}" IsReadOnly="True" Name="dtSearch" />

视图模型
    private ObservableCollection<MyDataClass> myData;
    public ObservableCollection<MyDataClass> MyData
    {
        get { return myData; }
        set
        {
            myData= value;
            RaisePropertyChanged("MyData");
        }
    }

可观察类
public partial class MyDataClass
{
    public int ID { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

有没有一种属性可以给我的ID属性,使其在DataGrid中隐藏?
我需要为可见属性创建另一个类吗?

有没有一个可见性属性可以在OnDataBound事件的基础上设置列的快捷方式或快捷键来完成这个操作? - MethodMan
问题在于我没有自己定义列,我相信DataGrid是根据ObservableCollection的内容创建它们的。 - Ryan Searle
4个回答

9
无论数据是否位于ObservableCollection中,这个问题都会发生。
为了解决这个问题,必须设置网格不自动生成列。这是通过设置属性AutoGenerateColumns=False,然后在xaml中指定所需的列来完成的。
<DataGrid ItemsSource="{Binding  MyData}" AutoGenerateColumns="False" >
   <DataGrid.Columns>
      <DataGridTextColumn Header="The Code"
                          Binding="{Binding Code}"/>
      <DataGridTextColumn Header="The Name"
                          Binding="{Binding Name}"/>
      <DataGridTextColumn Header="The Type"
                          Binding="{Binding Type}"/>
   </DataGrid.Columns>
  </DataGrid>

数据网格(DataGrid)文档中了解更多列选项。


7
WPF 数据绑定引擎会绑定对象的所有公共属性。因此,最简单的方法是将您的 ID 属性设置为内部(如果不会破坏其他代码)。 然而,当绑定对象列表时,有一种更通用的方法。首先,在某个常见的地方放置以下内容:
public class BindableCollection<T> : ObservableCollection<T>, ITypedList
{
    string ITypedList.GetListName(PropertyDescriptor[] listAccessors) { return null; }
    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
    {
        return TypeDescriptor.GetProperties(typeof(T), PropertyFilter);
    }
    static readonly Attribute[] PropertyFilter = { BrowsableAttribute.Yes };
}

请使用那个类来替代 ObservableCollection<T>。然后只需使用 Browsable 属性来隐藏项目类的成员即可。对于您的示例,代码如下:

视图模型

private BindableCollection<MyDataClass> myData;
public BindableCollection<MyDataClass> MyData
{
    get { return myData; }
    set
    {
        myData= value;
        RaisePropertyChanged("MyData");
    }
}

可观察类

public partial class MyDataClass
{
    [Browsable(false)]
    public int ID { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

将 ID 更改为内部 did 即可解决问题,不过我会选择 @OmegaMans 的方法,因为它提供了其他的好处,比如允许更改字段名称。感谢您的回答。 - Ryan Searle
1
没问题,虽然我个人更喜欢从 VM 控制大部分方面。我宁愿使用第二种方法,结合 DisplayName 或一些 DataAnnotations 属性,如此处所述:https://dev59.com/l1XTa4cB1Zd3GeqPxgBS - Ivan Stoev

2

XAML:

  <DataGrid x:Name="dataGrid1" Margin="0" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
                <DataGridTextColumn Binding="{Binding Code}" Header="Code"/>
                <DataGridTextColumn Binding="{Binding Type}" Header="Type"/>
            </DataGrid.Columns>
   </DataGrid>

代码后台:
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        ObservableCollection<MyDataClass> data = new ObservableCollection<MyDataClass>();
        data.Add(new MyDataClass { Code = "Code 1", ID = 1, Name = "Name 1", Type = "Type 1" });
        data.Add(new MyDataClass { Code = "Code 2", ID = 2, Name = "Name 2", Type = "Type 2" });
        data.Add(new MyDataClass { Code = "Code 3", ID = 3, Name = "Name 3", Type = "Type 3" });
        data.Add(new MyDataClass { Code = "Code 4", ID = 4, Name = "Name 4", Type = "Type 4" });
        data.Add(new MyDataClass { Code = "Code 5", ID = 5, Name = "Name 5", Type = "Type 5" });

        dataGrid1.ItemsSource = data;
    }

结果:

enter image description here


0

你可以在DataGrid对象的AutoGeneratedColumns事件中修改列。你可以重命名它们并删除那些不想显示的列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接