1

Currently, I'm making an Editor with MVVM pattern in WPF. Editor simply take an instance of a specific type as a reference and modifies it. The following code is the expected usage when editor development is completed.

MyEditor myEditor = new MyEditor();
myEditor.Show();
myEditor.Edit(myDataInstance1); // Bind myDataInstance1 to the editor and edit it.
myEditor.Edit(myDataInstance2);
myEditor.Clear();
myEditor.Close();
... and so on ...

So, I first divided the program into Model, ViewModel, and View. But, one question arose here. Where should I declare the Show(), Edit(), Clear(), Close() methods? And how should each View and ViewModel class be handled? I thought about it like this, but I didn't come up with a good alternative.

  • In the View constructor, set ViewModel to DataContext, create an instance of View, and access the DataContext of View and call the ViewModel method...
  • Directly access to the ViewModel methods. (View and ViewModel must be managed separately)
  • Create an independent class called MyEditor to manage View and ViewModel, and connect ViewModel's methods and MyEditor's methods. Users use the method of MyEditor.

Of the methods I thought, the third method is the most likely, but I'm not sure. The composition of the editor is not very simple. Basically, the Editor is largely composed of View, ViewModel, and Model, but inside the ViewModel, i must also handle with sub views for various MyChildTypes that can be edited. (There are several MyChildType classes that inherit MyBaseType class, and each MyChildType has its own editable View.) So, if I pass an instance of MyChildType to the Editor, the Editor should show an editable view suitable for that type. Type check and sub view replacement itself is easy, but, I don't know a proper way to set the MyChildType instance to the editor. Please advise me.

0

Generally the MMVM approach requires that the View be statically created via XAML.

When you have views which exist dynamically, change your code so that instead they always exist and are visible dynamically.

So in your case you would have something like

<MainWindow>
    <MyEditor ViewModel={Binding EditorViewModel}/>
</MainWindow>

and in your control...

<MyEditor>
   <Panel Visible={Binding IsVisible}>
    .... actual stuff...
   </Panel>
</MyEditor>

where EditorViewModel.IsVisible is initially false (and has appropriate binding)

You can then have EditorViewModel.Load(data) .Clear() .Show() .Hide() etc etc

3
  • Then the general usage of MyEditor is (1) The user creates MyEditor in XAML, (2) The user declares and binds EditorViewModel in the Code Behind or his own ViewModel, (3) and manipulate EditorViewModel instance. Soon, is it correct to put the Load(), Clear(), Show() methods to the EditorViewModel? – wddfrwd Sep 8 '20 at 14:11
  • Also, should I handle the Sub View used inside MyEditor in the same way? (Sub View for each MyChildType is created in MyEditor xaml, and each MyChildType ViewModel instance is created and managed in MyEditor ViewModel) – wddfrwd Sep 8 '20 at 14:19
  • yes and yes, although you can do some clever stuff with databinding and templates for your subviews if you want to be neat – Ewan Sep 8 '20 at 16:12
0

Have a look at caliburn micro

Its a convention based framework, so if yuo have a viewmodel it will automaticly show the view for that model. So you can change the view just by changing the viewmodel instance.

You can take a look at my open source software here that does this

https://github.com/AndersMalmgren/FreePIE

If you dont use a convention based tool like caliburn you could look into WPF ICommand pattern

edit: here is an example, we have a baseclass ViewModel property

https://github.com/AndersMalmgren/FreePIE/blob/4e51cae1816e3eee915a9629503cb7c188579550/FreePIE.GUI/Views/Plugin/PluginPropertyViewModel.cs#L35

public ValueViewModel Value  { get; set; }

In the view be bind to this by convention

https://github.com/AndersMalmgren/FreePIE/blob/4e51cae1816e3eee915a9629503cb7c188579550/FreePIE.GUI/Views/Plugin/PluginPropertyView.xaml#L11

 <ContentControl x:Name="Value"></ContentControl>

What ever viewmodel you reference the correct view will be displayed.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.