There is a main MainViewModel and MyUserControl (it has its own ViewModel).

public class MainViewModel { public ObservableCollection<String> StringList; public MainViewModel() { StringList = new ObservableCollection<string>(); } } 

Suppose you want to transfer a collection of rows from MainViewModel to a UserControl.

 <Window x:Class="UCandVM.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:UCandVM" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <local:MainViewModel></local:MainViewModel> </Window.DataContext> <Grid> <local:MyUserControl Items="{Binding StringList}"></local:MyUserControl> </Grid> 

How to get the StringList collection in ViewModel and MyUserControl?

 public class MyUserControlVM { //здесь работать с Items который приходит от MyUserControl } 

UPD1

But the question is: what for another control to see the same Items? What object does this control render? If it is the same object, then the VM is the same. If this is a different object, why do the two objects have a common part?

I answer the question, yes it is another object.

It may be that several UserControl take the same data and process it in their own VM, then output the result in the View :

 <Grid> <StackPanel> <local:MyUserControl Items="{Binding StringList}"></local:MyUserControl> <local:MyUserControl2 Items="{Binding StringList}"></local:MyUserControl2> </StackPanel> </Grid> 

Add another MyUserControl2 (from your VM), which also accepts the StringList collection from MainVM. Each control processes its own collection in its own way, and displays the result of processing in the View .

First UserControl

 <UserControl x:Class="UCandVM.MyUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:UCandVM" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" x:Name="root"> <UserControl.DataContext> <local:MyUserControlVM></local:MyUserControlVM> </UserControl.DataContext> <Grid> <StackPanel> <TextBlock Text="Результат обработки UC1:"></TextBlock> <TextBlock Text="{Binding result}"></TextBlock> </StackPanel> </Grid> 

Second UserControl

 <UserControl x:Class="UCandVM.MyUserControl2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:UCandVM" mc:Ignorable="d" x:Name="root" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.DataContext> <local:MyUserControl2VM></local:MyUserControl2VM> </UserControl.DataContext> <Grid> <StackPanel> <TextBlock Text="Результат обработки UC2:"></TextBlock> <TextBlock Text="{Binding result}"></TextBlock> </StackPanel> </Grid> 

As a result, in order for UserControl to work, it needs to transfer some information from MainVM, then work with it in the VM control. Actually how to access this kind of information in the VM control? Or how to get data from the DependecyProperty (defined in the control) in the VM control.

  • And where do you create MyUserControlVM and how do you use it? - andreycha
  • No, no, you are doing wrong. If UserControl has its own VM, then you should write something like <local:MyUserControl DataContext="{Binding SubVM}" /> , where SubVM is a property of type MyUserControlVM in MainViewModel . - VladD
  • @andreycha, 'MyUserControlVM' is a separate class, in 'MainViewModel' there is no property of type MyUserControlVM. I bind to it like this, '<UserControl.DataContext> <local: MyUserControlVM /> </UserControl.DataContext>' - Gardes
  • @VladD, in that case, as far as I understand, 'Items' should lie inside 'SubVM' and there will be no possibility to transfer it to other controls that have other VMs? - Gardes
  • @ S.KosT: Technically not necessary. If several different VMs contain a link to the same collection, their View can work with it. But the question is: what for another control to see the same Items? What object does this control render? If it is the same object, then the VM is the same. If this is a different object, why do the two objects have a common part? (Let's think in object-oriented terms.) - VladD

1 answer 1

The problem is this: you set the DataContext right inside the control! So you should not do it, because with this you will have it not connected with the outside world. You must install the DataContext outside, something like this:

 <local:MyUserControl DataContext="{Binding SubVM}" /> 

where SubVM is a property of type MyUserControlVM in MainViewModel .

If several controls should have access to the shared collection, put a link to the same collection in their VM. If you create slave VMs not from XAML, but manually, you can correctly initialize them and link them in the way you want.