Question

I've got a usercontrol which defines a ContentControl like this:

<ContentControl x:Name="PART_contentHost" Grid.Row="1"/>

In the viewmodel I will get a viewModel which will be displayed inside the contentControl. To establish the link with the view I have a datatemplate that establish the relationship between both of them.

<DataTemplate DataType="{x:Type ViewModels:Test1ViewModel}">
        <Views:Test1View />
</DataTemplate>

This means that I want Test1ViewModel to be shown inside the contentControl. I am not able to stablish that in my code C#.

//this gets the contentControl from de template
contentHost = this.Template.FindName(contentHostName, this) as ContentControl; 
//this assigns the test1ViewModel
contentHost.Content = content

What am I missing?

Was it helpful?

Solution

You have not shared enough code for me to be sure what you are trying to do. While there are cases in which you will need to parse templates, most often there is a better way. So here is how I understand your case in a MVVM context, can you do it this way?

enter image description here

Xaml:

<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>
<Window.Resources>
    <DataTemplate DataType="{x:Type local:Test1ViewModel}">
        <local:Test1View />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ContentControl Content="{Binding ContentModel}" />
</Grid>

Test1View:

<UserControl x:Class="WpfApplication1.Test1View" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <TextBlock Text="{Binding Name}" Background="Beige" Padding="5"  />
        <TextBlock Text="{Binding Address}" Background="PeachPuff" Padding="5" />
    </StackPanel>
</UserControl>

ViewModels:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private Test1ViewModel _contentModel;
    public Test1ViewModel ContentModel { get { return _contentModel; } set { _contentModel = value; OnPropertyChanged("ContentModel"); } }

    public ViewModel()
    {
        this.ContentModel = new Test1ViewModel() { Name = "John Higgins", Address = "Wishaw" };
    }

}

public class Test1ViewModel : INotifyPropertyChanged
{
    private string _name;
    public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } }

    private string _address;
    public string Address { get { return _address; } set { _address = value; OnPropertyChanged("Address"); } }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

OTHER TIPS

I have done something of that nature before. This code should get you started.

    public void FindAndSetTemplateContent( ContentControl target, ViewModelBase item)
    {
        if (target == null)
            throw new ArgumentNullException("target");

        if (item == null)
            throw new ArgumentNullException("item");

        var template = target.TryFindResource(new DataTemplateKey(item.GetType())) as DataTemplate; // this will pick up your resource for the viewmodel
        if (template == null)
            return null;

        var content = template.LoadContent() as ContentControl ;
        if (content != null)
        {
            content.DataContext = item;
        }
        return content;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top