WPF - MVVM - привязка UserControl - PullRequest
1 голос
/ 18 марта 2019

Я пытаюсь реализовать простой пример UserControl, показывающий в TextBox текущий DateTime, обновляемый четыре раза каждую секунду.

Я создаю простой пользовательский элемент управления:

<UserControl x:Class="UC.TestUC"
             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:UC"
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="100">
    <d:UserControl.DataContext>
        <local:TestUC_VM/>
    </d:UserControl.DataContext>
    <Grid Background="Azure">
        <TextBox Text="{Binding TestString}"/>
    </Grid>
</UserControl>

Где его ViewModel:

namespace UC
{
    public class TestUC_VM : INotifyPropertyChanged
    {
        private string _testString;
        public string TestString
        {
            get => _testString;
            set
            {
                if (value == _testString) return;
                _testString = value;
                OnPropertyChanged();
            }
        }

        public TestUC_VM()
        {
            TestString = "Test string.";
        }

        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

MainWindow XAML:

<Window x:Class="UC.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:UC"
        mc:Ignorable="d"
        Title="MainWindow" Height="100" Width="200">
    <Window.DataContext>
        <local:MainWindow_VM/>
    </Window.DataContext>
    <Window.Resources>
        <local:TestUC_VM x:Key="TestUC_VM"/>
    </Window.Resources>
    <Grid>
        <local:TestUC DataContext="{StaticResource TestUC_VM}"/>
    </Grid>
</Window>

И его ViewModel:

namespace UC
{
    public class MainWindow_VM
    {
        public TestUC_VM _uc_VM;

        public MainWindow_VM()
        {
            _uc_VM = new TestUC_VM();
            Task.Run(() => ChangeString());
        }

        public async Task ChangeString()
        {
            while (true)
            {
                _uc_VM.TestString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                await Task.Delay(250);
            }
        }
    }
}

Даже если я вижу в отладчике, что я 'м, проходя через установщик TestString, MainWindow не обновляется.Я вполне уверен, что упустил что-то тривиальное в настройке DataContext UC в MainWindow, но я не смог найти то, что после нескольких часов просмотра и размышлений.

Любая помощь приветствуется.

1 Ответ

1 голос
/ 18 марта 2019

Выражение

<local:TestUC DataContext="{StaticResource TestUC_VM}"/>

назначает значение ресурса TestUC_VM для DataContext UserControl. Это объект, отличный от _uc_VM члена модели основного вида, который вы позже обновляете.

Превратить участника в публичную собственность

public TestUC_VM UcVm { get; } = new TestUC_VM();

и напишите

<local:TestUC DataContext="{Binding UcVm}"/>

Обновите модель вида следующим образом:

UcVm.TestString = ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...