I'm basing this solution on the answer provided here and some other reading. I have a Data Template in App.xaml to that sets the data type to my viewmodel and the corresponding view. Within MainWindow.xaml, I'm binding to a list and rendering a ContentControl using this Data Template. Finally, the actual view has a label and a textbox within.
I understand MVVM just fine, but the way WPF implements it is new to me, and I just haven't been able to get it wired up. In the view's code-behind, the DataContext is null as it's being instantiated. Even explicitly setting the DataContext in the view's code-behind to a new view-model instance still doesn't bind these properties.
App.xaml
<Application x:Class="MessagePublisher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:MessagePublisher.UI.Components"
xmlns:viewModels="clr-namespace:MessagePublisher.ViewModels"
StartupUri="UI/MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type viewModels:StringPropertyViewModel}">
<views:StringView />
</DataTemplate>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="MessagePublisher.UI.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<ItemsControl ItemsSource="{Binding PropertyList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
var s = new CommonViewModel
{
TestList = new List<string>{"Test","List"},
PropertyList = new ObservableCollection<StringPropertyViewModel>
{
new StringPropertyViewModel
{
PropertyName = "Dog", Value = "Rascal"
},
new StringPropertyViewModel
{
PropertyName = "Cat", Value = "Mia"
}
}
};
InitializeComponent();
DataContext = s;
}
}
StringView.xaml
<UserControl x:Class="MessagePublisher.UI.Components.StringView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding PropertyName}"></Label>
<TextBox Grid.Column="1" Text="{Binding Value}"></TextBox>
</Grid>
</UserControl>
StringView.xaml.cs
public partial class StringView : UserControl
{
public StringView()
{
InitializeComponent();
}
}
StringPropertyViewModel
public class StringPropertyViewModel
{
public string PropertyName;
public string Value;
}
When I run my app, I see the correct number of StringView rows rendered out, but the data binding doesn't appear to be working and the labels and text boxes are all empty. If I replace the data bindings in the view with static text, that shows just fine. There are no exceptions presented, it just shows renders as empty.
Ultimately, I'd expect the MainWindow to have two rows which represent StringViews. The first row should have a label that says "Dog" and the textbox to have a value of "Ralph." The second row should have a label that says "Cat" and the textbox to have a value of "Mia."
I've already put way too much time into this. Any assistance is much appreciated!