0

So I have 4 classes, for example:

Class A Inherits I
Public name as String
Public ID as Integer

Class B Inherits I
Public test as String
Public somethingElse as Integer

Class C Inherits I
Public banana as String
Public Type as String
Public length as Integer

Class D Inherits I
Public name as String
Public ID as String

Say I have a ComboBox in my WPF application that contains a list of I objects (some are of type Class A, some of type Class C, etc etc etc.).

When one is selected, I want the datagrid to populate with the public variables of the selected class - variable names in the left column and values in the right.

I want the right-hand column to be editable, but not to update the variables in the class directly.

My questions are, then - how do I bind the datagrid to the selected class if all/some of the variables are different in each class? And how do I then keep the association with the variable, so I can update it later if the changes the user makes passes my custom validation?

My idea (that I don't know how to implement):

  • Would each class need some sort of converter method that the DataGrid can bind to? but if so, what would that method return?

  • Would I just have to keep track that row 1 contains this variable, etc. for each class, so I can update later?

simonalexander2005
  • 4,338
  • 4
  • 48
  • 92

1 Answers1

1

Perhaps if you had tried this before asking your question, then you would already have your answer? In WPF, the DataGrid control provides functionality that will auto generate its columns. In fact, that is the default behaviour and you have to turn it off if you don't want it. In your case however, it sounds like you want it left on.

You'll need an ObservableCollection<I> property in your code behind or view model to data bind to the DataGrid.ItemsSource property... let's call it Items:

<DataGrid ItemsSource="{Binding Items}" />

Now here's the tricky part when you change the type of objects in the collection and have to attempt to data bind all of the new properties to the DataGrid.Columns collection:

List<A> classAItems = GetClassAItems();
Items = new ObservableCollection<I>(classAItems);

That's it! Show a different class?:

List<B> classBItems = GetClassBItems();
Items = new ObservableCollection<I>(classBItems);

That's it!


UPDATE >>>

how can I have two columns - "field" and "value", with each variable populating a row?

I seem to have inadvertently answered your follow up question earlier, rather than you actual question. To get all column headers correctly populated, you should use an ObservableCollection<object> instead. To have only the common properties populated in the column headers, you should declare an interface with just those properties in. After implementing that interface in all of your classes, you will then be able to display them all in the same DataGrid (even mixed in the same collection).

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Thanks for this, I'm getting somewhere with it. Rather than putting the variable names as the column headings, how can I have two columns - "field" and "value", with each variable populating a row? – simonalexander2005 Sep 01 '14 at 15:54
  • RE: Update - Thanks, but that's not what I mean. I don't want the properties to be the column headers, I want them to be "row headers", if you like, instead. so my datagrid will ALWAYS have two columns, no matter how many properties I have. Does that make sense? – simonalexander2005 Sep 01 '14 at 16:08
  • You'll need to restructure your data collection accordingly to accomplish that. – Sheridan Sep 01 '14 at 16:12
  • Thanks. One last question then - how can I hide Properties from the databinding, without also hiding them from other data bindings in the same GUI? For example, if I have a string in the parent class that needs to be bound to a label, but then shouldn't show in the datagrid, is this accomplishable? – simonalexander2005 Sep 02 '14 at 08:48
  • I'll ask this as a separate question – simonalexander2005 Sep 02 '14 at 08:59
  • http://stackoverflow.com/questions/25619724/hide-a-property-from-an-observablecollection here – simonalexander2005 Sep 02 '14 at 09:07