0

I googled for an answer to this for more than two weeks now. This usually means either I am blind or the idea is absurd. Anyways:

In a middle-sized, quite flexible project I'm storing configuration data in a hierarchical structure in the like of this one:

  • Configuration (collection)
    1. Audio (class)
      • BaseDir (struct)
      • PlayMode (enum)
      • Input (class)
      • CalibrateOnConnect (bool)
      • KnownDevices (collection)
        1. ... (class)
          • ...
      • UseDevice (integer)
      • Playlist (collection)
        1. FirstAudio (class)
          • Path (string)
          • Repeat (integer)
      • ...

I already managed to display these in a TreeView in a MVVM pattern. Since I can't exactly tell which options will be added in future, I used a generic approach, creating ViewModels for class, ienumerable, my custom structs and the basic value types (string, bool, enum, ...).

In my XAML these have their corresponding (Hierarchical)DataTemplates, e.g. with a CheckBox for booleans or a textblock for general value types.

Each ViewModel instance has a field to store the data of the underlying Model.

I manage to edit these values in the View and via TwoWay-Binding also in the ViewModel.
But what makes my head hurt is how to update this data in the Model.
Since I create the hierarchical ViewModel structure through reflection, the parents do not have get/set properties corresponding to the field names / indexers / ... of the equivalent configuration class / collection. Though each ViewModel instance knows the field/property name of the parent's model's data structure it was created from and knows its parent ViewModel instance, too (but not its parent Model instance).
Every attempt to solve this problem via Commands or by calling some parent's update function made a knot into my brain.

Isn't there a simple way to achieve this via regular binding techniques?
Would it be better if I created ViewModels for each configuration (sub)class I'm using?
Hint: Each ViewModel instance knows its field / property name in the parent's model's data structure.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Martin Hennings
  • 16,418
  • 9
  • 48
  • 68
  • What are you gaining by creating view-models for `string`, `bool`, `enum`, `ienumerable`, *etc.*? Why not just bind to these directly? If the view-model doesn't know how to manipulate the model, then I wouldn't consider it a view-model at all. – Jay Jul 15 '10 at 17:07
  • Because the ViewModel for a class doesn't know which exact fields it contains, so the TreeViewItem for any class contains a Subitem for each field and parameter, which may itself be a class again. Thinking from C++ I would use some reference to store a "pointer" to the field (which is being accessed in the constructor call of the specific ViewModel). – Martin Hennings Jul 16 '10 at 07:03
  • I understand now that there is no such thing as a "generic ViewModel", which I think is sad. Instead for any Model class present there must be a specific ViewModel and a specific View. – Martin Hennings Jul 27 '10 at 13:36

1 Answers1

1

Reading through the comments I'd argue that a view model should be tightly coupled to the model that it is trying to represent. Having a dynamic view model is also very hard to test.

However, if you really wanted to try to get around this, you could consider using a DynamicObject which allows you to get/set properties on the instance in a completely generic fashion. With DynamicObjects you are then given hooks that are called when a property is either set or got, this would enable you (for example) to raise NotifyPropertyChange events for a given dynamic property.

The Senator
  • 5,181
  • 2
  • 34
  • 49