6
votes

The following code-behind binding works for the SmartFormView user control:

View:

<UserControl x:Class="CodeGenerator.Views.PageItemManageSettingsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:v="clr-namespace:CodeGenerator.Views"
    xmlns:vm="clr-namespace:CodeGenerator.ViewModels"
    Background="#ddd">

    <Grid Margin="10">
        <ScrollViewer DockPanel.Dock="Top">
            <StackPanel Margin="10">
                <v:SmartFormView/>
            </StackPanel>
        </ScrollViewer>
    </Grid>

</UserControl>

Code-behind:

using System.Windows.Controls;
using CodeGenerator.ViewModels;

namespace CodeGenerator.Views
{
    public partial class SmartFormView : UserControl
    {
        public SmartFormView()
        {
            InitializeComponent();
            DataContext = new SmartFormViewModel("testing");
        }
    }
}

However, I want to bind the SmartFormView to its SmartFormViewModel in the ViewModel of the calling View, not hard-coded in the code-behind. Yet these two approaches don't bind:

<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:SmartFormViewModel}">
    <v:SmartFormView/>
</DataTemplate>
</UserControl.Resources>

...

<Grid Margin="10">
<ScrollViewer DockPanel.Dock="Top">
    <StackPanel Margin="10">
        <TextBlock Text="{Binding Testing}"/>
        <v:SmartFormView DataContext="{Binding SmartFormViewModel}"/>
        <ContentControl Content="{Binding SmartFormViewModel}"/>
    </StackPanel>
</ScrollViewer>
</Grid>

In the ViewModel I have "Testing" and "SmartFormViewModel" defined as ViewModel properties and fill them both (as shown below), but although the Testing property binds fine, the the SmartFormView does not bind to its SmartFormViewModel:

private SmartFormViewModel _smartFormViewModel=;
public SmartFormViewModel SmartFormViewModel
{
    get
    {
        return _smartFormViewModel;
    }
    set
    {
        _smartFormViewModel = value;
        OnPropertyChanged("SmartFormViewModel");
    }
}

private string _testing;
public string Testing
{
    get
    {
        return _testing;
    }    
    set
    {
        _testing = value;
        OnPropertyChanged("Testing");
    }
}

public PageItemManageSettingsViewModel(MainViewModel mainViewModel, PageItem pageItem)
    : base(mainViewModel, pageItem)
{
    SmartFormViewModel SmartFormViewModel = new SmartFormViewModel("manageSettingsMain");
    Testing = "test ok";
}

What is the syntax to bind a UserControl in XAML to a specific ViewModel in the calling View's ViewModel?

1

1 Answers

6
votes

Could be wrong, but I think you just have a bug in your code.

SmartFormViewModel SmartFormViewModel = new SmartFormViewModel("manageSettingsMain");

Should be:

SmartFormViewModel = new SmartFormViewModel("manageSettingsMain");

ie. Your SmartFormViewModel is never being set. Therefore, the binding you have in your parent view doesn't find it.

Further to this, a better way to do this is just to stick your child VM into the visual tree:

<ContentControl Content="{Binding SmartFormViewModel}"/>

And use a DataTemplate to do the resolution of the view rather than "hard-coding" the view into the, um, parent view.