How to initialize a nested view (and ViewModel) without using a dependent converter in WPF / MVVM

I am developing a WPF application after the MVVM pattern. In one UserControl (and in fact this situation happens many times), since it is quite complicated, including, for example, TabControl , I would like to divide them into several sub UserControl . For example, in the "main" view, let it call MainUC, I have a TabControl that has two TabItem . Since both TabItem actually include many user interface elements, I design two UserControl , SubUCA and SubUCB, so the XAML MainUC looks like this:

 <TabControl Name="mainUC" Grid.Row="0" > <TabItem Header="Sub UC A" Name="SubUC1"> <local:SubUCA /> </TabItem> <TabItem Header="Sub UC B" Name="SubUC2"> <local:SubUCB /> </TabItem> </TabControl > 

But now my question is: how do I organize ViewModel (s) for these UserControl ? One of the methods that I currently use has only one ViewModel class (called MainUC_VM), and the DataContext from MainUC is set to this instance of the class (note that I do not use dependency injection, so I just create an instance in the code notation MainUC). But in this way, the MainUC_VM class would become very complex, as would MainUC. Therefore, I would also like to split the ViewModel into several classes. For example, in the class MainUC_VM I can have such properties

 public SubUCA_VM SubVM1 { get; set; } public SubUCB_VM SubVM2 { get; set; } 

However, since I do not use dependency injection (because our team did not decide to use it), how can I make SubVM1 and SubVM2 become DataContext for SubUC1 and SubUC2 respectively? I cannot create an instance of one of the codes underlying SubUCA and SubUCB, as they will be different from the property elements in MainUC_VM.

Some ways I can think of are: 1) making the SubUCA_VM and SubUCB_VM singleton classes (which is similar to the same dependency injection behavior, for example, the default MEF) or 2) using the EvengAggregator to notify the instance of the object. But in any case, it seems to add unnecessary complexity, in my opinion. Does this mean that dependency injection is almost mandatory for using MVVM? Is there any way to achieve this without using DI?

+6
source share
1 answer

You can use implicit data templates to bind your data (VM) to your views. First, define data patterns in the resource dictionary available for your MainUC . This can be either in the user control itself, or even in the application resources. These data patterns instruct WPF, which monitors usage when it needs to present data of a particular type.

 <UserControl.Resources> <DataTemplate TargetType="{x:Type local:SubUCA_VM}"> <local:SubUCA /> </DataTemplate> <DataTemplate TargetType="{x:Type local:SubUCB_VM}"> <local:SubUCB /> </DataTemplate> </UserControl.Resources> 

Then bind the contents of the tabs to the child virtual machines:

 <TabControl Name="mainUC" Grid.Row="0" > <TabItem Header="Sub UC A" Content="{Binding SubVM1}" /> <TabItem Header="Sub UC B" Content="{Binding SubVM2}" /> </TabControl> 

Alternatively, you can have a list of child virtual machines in your main virtual machine. Each child virtual machine must have a Title property, so the tab control can use it for the title. Thus, the main virtual machine can dynamically create a user interface. You still need the data patterns mentioned above.

 <TabControl ItemsSource="{Binding Children}" DisplayMemberPath="Title" /> 
+4
source

Source: https://habr.com/ru/post/956402/


All Articles