ViewModel data will not bind to UserControl exclusively

  .net-5, data-binding, windows, wpf

I have a simple test ViewModel for my MainWindow:

namespace MyApp.ViewModels
{
    class MainWindowViewModel : ViewModelBase
    {
        public string Test { get; set; } = "TEST";
    }
}

Can’t get any simpler than that. Now I give my MainWindow knowledge about it and bind the Test property to a TextBox and an own UserControl:

<Window x:Class="MyApp.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:MyApp"
                xmlns:uc="clr-namespace:MyApp.UserControls"
                xmlns:vm="clr-namespace:MyApp.ViewModels"
                mc:Ignorable="d"
                Width="800"
                Height="600">
    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox HorizontalAlignment="Left"
                             Grid.Row="0"
                             TextWrapping="Wrap"
                             VerticalAlignment="Top"
                             Width="120"
                             Text="{Binding Test, PresentationTraceSources.TraceLevel=High}" />

        <uc:TestUserControl Grid.Row="1" Test="{Binding Test, PresentationTraceSources.TraceLevel=High}" />

    </Grid>
</Window>

Again, very simple.

My TestUserControl looks like that:

<UserControl x:Class="MyApp.UserControls.TestUserControl"
             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:MyApp.UserControls"
                         mc:Ignorable="d"
                         DataContext="{Binding RelativeSource={RelativeSource Self}}"
                         d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBox HorizontalAlignment="Left"
                         TextWrapping="Wrap"
                         VerticalAlignment="Top"
                         Width="120"
                         Text="{Binding Test, PresentationTraceSources.TraceLevel=High}" />
    </Grid>
</UserControl>
namespace MyApp.UserControls
{
    public partial class TestUserControl : UserControl
    {
        public static readonly DependencyProperty TestProperty =
                DependencyProperty.Register("Test", typeof(string), typeof(TestUserControl),
                        new FrameworkPropertyMetadata((string)String.Empty));

        public string Test
        {
            get { return (string)GetValue(TestProperty); }
            set { SetValue(TestProperty, value); }
        }


        public TestUserControl()
        {
            InitializeComponent();
        }
    }
}

What I basically end up with are two TextBoxes, one wrapped in my UserControl, the other not.

Both TextBoxes should contain the text "TEST", but only the one that is not embedded in the UserControl does.

When I skip the binding of the ViewModel like so:

<uc:TestUserControl Grid.Row="1" Test="TEST" />

The text shows up in the TextBox, which indicates that the user control is fine. I know that I miss the entire INotifyPropertyChanged stuff, but the TextBox that is not wrapped in the UserControl is able to bind the property. Doing this does not fix the bug:

namespace MyApp.ViewModels
{
    class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public MainWindowViewModel()
        {
            this.Test = "TEST";
        }

        private string test;

        public string Test
        {
            get { return test; }
            set {
                test = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Test))); 
            }
        }
    }
}

Output:

System.Windows.Data Warning: 56 : Created BindingExpression (hash=52579650) for Binding (hash=50581426) BindingExpression:Path=Test; DataItem=null; 
System.Windows.Data Warning: 58 :  Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=52579650): Default mode resolved to TwoWay
System.Windows.Data Warning: 61 : BindingExpression (hash=52579650): Default update trigger resolved to LostFocus
System.Windows.Data Warning: 62 : BindingExpression (hash=52579650): Attach to System.Windows.Controls.TextBox.Text (hash=15537542)
System.Windows.Data Warning: 67 : BindingExpression (hash=52579650): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=52579650): Found data context element: TextBox (hash=15537542) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=52579650): Activate with root item MainWindowViewModel (hash=13189358)
System.Windows.Data Warning: 108 : BindingExpression (hash=52579650):   At level 0 - for MainWindowViewModel.Test found accessor RuntimePropertyInfo(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=52579650): Replace item at level 0 with MainWindowViewModel (hash=13189358), using accessor RuntimePropertyInfo(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=52579650): GetValue at level 0 from MainWindowViewModel (hash=13189358) using RuntimePropertyInfo(Test): 'TEST'
System.Windows.Data Warning: 80 : BindingExpression (hash=52579650): TransferValue - got raw value 'TEST'
System.Windows.Data Warning: 89 : BindingExpression (hash=52579650): TransferValue - using final value 'TEST'
System.Windows.Data Warning: 56 : Created BindingExpression (hash=26543418) for Binding (hash=62601592) BindingExpression:Path=Test; DataItem=null; 
System.Windows.Data Warning: 58 :  Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=26543418): Default mode resolved to TwoWay
System.Windows.Data Warning: 61 : BindingExpression (hash=26543418): Default update trigger resolved to LostFocus
System.Windows.Data Warning: 62 : BindingExpression (hash=26543418): Attach to System.Windows.Controls.TextBox.Text (hash=21868813)
System.Windows.Data Warning: 67 : BindingExpression (hash=26543418): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=26543418): Found data context element: TextBox (hash=21868813) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=26543418): Activate with root item TestUserControl (hash=21522166)
System.Windows.Data Warning: 108 : BindingExpression (hash=26543418):   At level 0 - for TestUserControl.Test found accessor DependencyProperty(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=26543418): Replace item at level 0 with TestUserControl (hash=21522166), using accessor DependencyProperty(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=26543418): GetValue at level 0 from TestUserControl (hash=21522166) using DependencyProperty(Test): ''
System.Windows.Data Warning: 80 : BindingExpression (hash=26543418): TransferValue - got raw value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=26543418): TransferValue - using final value ''
System.Windows.Data Warning: 56 : Created BindingExpression (hash=3865173) for Binding (hash=22799085) BindingExpression:Path=Test; DataItem=null; 
System.Windows.Data Warning: 58 :  Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=3865173): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=3865173): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=3865173): Attach to MyApp.UserControls.TestUserControl.Test (hash=21522166)
System.Windows.Data Warning: 67 : BindingExpression (hash=3865173): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=3865173): Found data context element: TestUserControl (hash=21522166) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=3865173): Activate with root item TestUserControl (hash=21522166)
System.Windows.Data Warning: 107 : BindingExpression (hash=3865173):   At level 0 using cached accessor for TestUserControl.Test: DependencyProperty(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=3865173): Replace item at level 0 with TestUserControl (hash=21522166), using accessor DependencyProperty(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=3865173): GetValue at level 0 from TestUserControl (hash=21522166) using DependencyProperty(Test): ''
System.Windows.Data Warning: 80 : BindingExpression (hash=3865173): TransferValue - got raw value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=3865173): TransferValue - using final value ''

This should not happen, what is the reason for this issue and how to fix it?

Source: Windows Questions

LEAVE A COMMENT