I have a DataGrid
where the ItemSource
is an Observable Collection bound using MVVM
archetype. I would like to not show the ID property of the class displayed in my DataGrid
however I still need the property to exist.
My Code:
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
?
Do I need to create another class for visible properties?
This issue will happen regardless of whether the data resides in an ObservableCollection
or not.
To correct this, one must set the grid to not auto generate the columns. That is done by setting the property AutoGenerateColumns=False
and then in the xaml specify the columns desired.
<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.
WPF data binding engine binds to all public properties 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:
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 Browsable
attribute to hide members of the item class. For your example it's something like this:
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; }
}
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With