Rajeev Verma
Rajeev Verma

Reputation: 81

How to initialize a view model with properties from another view Model

My question is what is the ideal way to initialize child window in WPF, MVVM way?

I have a WPF window , let's call it as ParentWindow having its view Model class - ParentWindowViewModel. On click of a button on the ParentWindow UI , I launch a new WPF window - ChildWindow like below

ChildWindow  r = new ChildWindow ();
 r.ShowDialog();           
 r.WindowStartupLocation = WindowStartupLocation.CenterScreen;

Now, the ChildWindow has its own viewModel like - ChildWindowViewModel. The Child Window has the datacontext set in its xaml as

<Window.DataContext>
        <viewModel:ChildWindowViewModel/>
    </Window.DataContext>

On Click of button in the ParentWindow, When i Launch the Child Window, I need to pass certain values to the Child Window, which will be used to initialize the Child Window. Without these values the child window cannot be initialized.Every time I click the button to Launch the child window, the values being passed to child window will differ based on some other selected items in the Parent Window.

Upvotes: 1

Views: 3758

Answers (1)

Ginger Ninja
Ginger Ninja

Reputation: 797

I would do something like this (without error checking):

in ParentWindow.xaml.cs

private void Some_Event_In_Parent_Window()
{
   ParentWindowViewModel pvm = DataContext as ParentWindowViewModel;
   ChildWindow cw = new ChildWindow(pvm.Element1, pvm.Element2);
}

int ChildWindow.xaml.cs

public ChildWindow(bool elem1, string elem2)
{
   InitializeComponents();
   DataContext = new ChildWindowViewModel(elem1, elem2);
} 

If you are dealing with minimal elements that need to be transferred between windows/VM's, and it is mainly about sending some form of "state" or "value", then there isnt too much issue with initializing the Viewmodel in the code behind. Remember that the <viewmodel:ChildWindowViewModel/> is equivalent to DataContext = new ChildWindowViewModel() in your code behind. While yes, you can create spaghetti code, or confusing dependencies by not adhering to patterns; you can also over engineer the crap of something that did not require the effort and can be just as confusing.

I find that there is an obsession with keeping your code behind empty (i have the same obsession). Remember, that the Code behind is there for a reason, and you CAN use it. Sometimes it isnt worth over-complicating your code base by implementing some big pattern if you have a single one off requirement that can be handled in code behind with some added comments.

Aside from Event Handlers, I utilize the Code Behind for these main use cases:

  1. There is an adjustment needed to the UI that is too complicated to handle in the XAML alone. Example: I need a weird string concatenation and logic of some inputted text fields.
  2. There is some minimal state or data needed to be transferred between Views. (Like your requirement)
  3. There is some sort of logic that needs to happen that is UI specific and not related to the underlying data or ViewModel. (This is rare, and almost always a small one off).

In terms of "is this ideal" for MVVM; it depends on your definition of ideal.

  • Can this be handled by some other design pattern? Probably...? But is it worth it.
  • Does implementing said pattern add bloat or overhead that only solves a small problem? Maybe. That is for you to decide.
  • Are you going to be repeating this implementation more than once? If so you may have some bad design to rethink.
  • Does implementing this solution of using Code behind solve your issue in a speedy way, that is moderately maintainable and readable? If so, then I wouldnt see a problem.

Ideal is not always defined by rules. It is also specific to your needs and requirements.

It isnt always easy to determine where your use case should be handled. View, ViewModel, maybe a Service, or a Singleton state class. If your use case is this one window, Code behind is fine (In my opinion). If you are doing this for 20 windows, you may want a Service to maintain the state somehow. Think of it more - if your code is SOLID and DRY

Upvotes: 4

Related Questions