【问题标题】:Hide a Column from a DataGrid when the ItemSource is an Observable Collection当 ItemSource 是 Observable 集合时,隐藏 DataGrid 中的列
【发布时间】:2015-11-18 02:59:43
【问题描述】:

我有一个DataGrid,其中ItemSource 是一个使用MVVM 原型绑定的可观察集合。我不想显示在我的DataGrid 中显示的类的 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 事件执行此操作的快捷方式或快捷方式..?
  • 问题是我自己没有定义列,我相信 DataGrid 根据 ObservableCollection 的内容创建它们。

标签: c# wpf xaml mvvm observablecollection


【解决方案1】:

无论数据是否位于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 文档中的更多列选项。

【讨论】:

    【解决方案2】:

    WPF 数据绑定引擎绑定到对象的所有 public 属性。因此,最简单的方法是将您的 ID 属性设置为 internal(如果这不会破坏任何其他代码)。
    但是,当绑定到对象列表时,有一种更通用的方法。首先,将以下内容放在一些常见的地方:

    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&lt;T&gt;。然后只需使用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 更改为 internal 可以解决问题,但是我将决定使用 @OmegaMans 的方法,因为它提供了其他好处,例如允许更改字段名称。感谢您的回答。
    • 没关系。虽然我个人更喜欢从 VM 控制大部分方面。我宁愿将第二种方法与DisplayName 或一些DataAnnotations 属性结合使用,如此处所述stackoverflow.com/questions/5230402/…
    【解决方案3】:

    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;
        }
    

    结果:

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2012-12-21
        • 1970-01-01
        • 2017-07-31
        • 2021-02-09
        • 2011-09-10
        • 2016-09-18
        • 2015-08-18
        • 2011-04-29
        • 1970-01-01
        相关资源
        最近更新 更多