0

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!

Switch386
  • 454
  • 6
  • 19
  • 2
    Are `PropertyName` and `Value` in your StringPropertyViewModel actually properties? Not sure whether you already are aware of this, but note that WPF's binding mechanism does not work with fields. –  Jul 06 '19 at 18:12
  • blechhhhh yes, that was it. I spent hours on this. Please write an answer for this and I'll accept it. I'll also update my question to include the VM. – Switch386 Jul 06 '19 at 18:16
  • No need for an answer, duplicate question incoming ;-) –  Jul 06 '19 at 18:16
  • If you know where to look. Thanks for the help. – Switch386 Jul 06 '19 at 18:17
  • Flagging a duplicate question is not so much saying or or trying to tell you where to look. It's more a mechanism for saying/indicating that there is a question whose answer(s) is (are) answering this question here, too ;-) –  Jul 06 '19 at 18:19
  • Nah, I just meant I was focusing on the data context and data template piece of this. Completely looking at the wrong thing so I wasn't asking the right question. I do appreciate it! – Switch386 Jul 06 '19 at 18:22

0 Answers0