wpf – UserControlVIewModel working with UserControl properties

Question:

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>();
    }
}        

Let's say you need to pass a collection of strings from MainViewModel to 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 collection of StringList in ViewModel and MyUserControl?

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

UPD1

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

The answer to the question is, yes, this is a different object.

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

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

Let's add another MyUserControl2 (from our VM), which also accepts a StringList collection from MainVM. Each control processes the received collection in its own way, and displays the processing result 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 VM control. Actually, how to access this certain information in the VM control? Or how to get data from DependecyProperty (defined in control) in control VM .

Answer:

The problem is this: you are setting the DataContext right inside the control! You should not do this, because at the same time he will not be connected with the outside world. You have to set the DataContext outside, something like this:

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

where SubVM is a property of type MyUserControlVM in MainViewModel .

If several controls need to access a shared collection, put a reference to the same collection in their VM. If you create subordinate VMs not from XAML, but manually, you can properly initialize them and link them in the way you want.

Scroll to Top