wpf 当 ItemSource 是 Observable 集合时隐藏 DataGrid 中的列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32186505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:21:43  来源:igfitidea点击:

Hide a Column from a DataGrid when the ItemSource is an Observable Collection

c#wpfxamlmvvmobservablecollection

提问by Ryan Searle

I have a DataGridwhere the ItemSourceis an Observable Collection bound using MVVMarchetype. I would like to not show the ID property of the class displayed in my DataGridhowever I still need the property to exist.

我有一个DataGridItemSource是利用可观察集合约束MVVM原型。我不想显示显示在我的类的 ID 属性,DataGrid但是我仍然需要该属性存在。

My Code:

我的代码:

XAML

XAML

<DataGrid ItemsSource="{Binding MyData}" IsReadOnly="True" Name="dtSearch" />

View Model

查看模型

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

Observable Class

可观察类

public partial class MyDataClass
{
    public int ID { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

Is there an attribute I can give my ID property to hide it from the DataGrid?

有没有我可以给我的 ID 属性的属性来隐藏它DataGrid

Do I need to create another class for visible properties?

我是否需要为可见属性创建另一个类?

回答by ΩmegaMan

This issue will happen regardless of whether the data resides in an ObservableCollectionor not.

无论数据是否驻留在ObservableCollection.

To correct this, one must set the grid to notauto generate the columns. That is done by setting the property AutoGenerateColumns=Falseand then in the xaml specify the columns desired.

要纠正这一点,必须将网格设置为自动生成列。这是通过设置属性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>

Check out more column options in the documentation for the DataGrid.

查看DataGrid文档中的更多列选项。

回答by Ivan Stoev

WPF data binding engine binds to all publicproperties of the object. So, the simplest is to make your ID property internal(if that doesn't break any other code).
However, there is a more general approach when binding to a list of objects. First, put the following in some common place:

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

and use that class instead of ObservableCollection<T>. Then just use Browsableattribute to hide members of the item class. For your example it's something like this:

并使用该类而不是ObservableCollection<T>. 然后只需使用Browsable属性来隐藏项目类的成员。对于您的示例,它是这样的:

View Model

查看模型

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

Observable Class

可观察类

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

回答by jsanalytics

XAML:

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>

Code behind:

后面的代码:

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

Result:

结果:

enter image description here

enter image description here

回答by mstyrcz

You can modify columns in the AutoGeneratedColumnsevent of the DataGrid object. You can rename them and remove those that you don't want to be displayed.

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