Свойство привязки MainViewModel к SubView - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь выяснить, как связать свойство из моей MainWindowViewModel с ContentControl, основанным на другом представлении. Привязка RelativeSource, кажется, не работает, так как представление находится в другом файле xaml? Я попытался использовать свойство зависимости, но я не понял, как это сделать правильно, я думаю.

Здесь я хочу добиться того, чтобы при вводе TextBox в MainWindow все 3 представления (contentcontrols) также просмотреть обновленные данные. Это должна быть демонстрация, чтобы проиллюстрировать, что в MVVM ViewModel может меняться без знания представлений, и различные представления реагируют на него.

К сожалению, привязка RelativeSource и DependancyProperty не сработали для меня, или я упустил пункт.

MainWindow.xaml

<Window x:Class="MVVMDemo.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">
    <StackPanel>
        <TextBlock Text="MVVM Demo" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold"/>
        <TextBox Text="{Binding TestString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" Background="Black" Foreground="White" Margin="0 20 0 0"/>

        <Grid Margin="0 20 0 0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="300"/>
            </Grid.RowDefinitions>
            <ContentControl Grid.Column="0" Grid.Row="0" Content="{Binding ViewOne}"/>
            <ContentControl Grid.Column="1" Grid.Row="0" Content="{Binding ViewTwo}"/>
            <ContentControl Grid.Column="2" Grid.Row="0" Content="{Binding ViewThree}"/>

        </Grid>


    </StackPanel>
</Window>

MainWindowViewModel

    public class MainWindowViewModel : ViewModelBase
    {
        /// <summary>
        /// String to change the reaction of views
        /// </summary>
        private string _TestString;
        public string TestString
        {
            get { return _TestString; }
            set { _TestString = value; NotifyPropertyChanged(); }
        }

        private object _ViewOne { get; set; }
        public object ViewOne
        {
            get { return _ViewOne; }
            set { _ViewOne = value; NotifyPropertyChanged(); }
        }
        private object _ViewTwo { get; set; }
        public object ViewTwo
        {
            get { return _ViewTwo; }
            set { _ViewTwo = value; NotifyPropertyChanged(); }
        }
        private object _ViewThree { get; set; }
        public object ViewThree
        {
            get { return _ViewThree; }
            set { _ViewThree = value; NotifyPropertyChanged(); }
        }

        public MainWindowViewModel()
        {
            ViewOne = new ViewOne();
            ViewTwo = new ViewTwo();
            ViewThree = new ViewThree();
            TestString = "ABC";
        }
    }

ViewOneViewModel

<UserControl x:Class="MVVMDemo.Views.ViewOne"
             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:MVVMDemo.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="White">
        <StackPanel Orientation="Horizontal">

            <TextBlock Text="{Binding Path=TestString, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Foreground="Black"/>
            <TextBlock Text="{Binding TestStringProperty}" Foreground="Black"/>
        </StackPanel>


    </Grid>
</UserControl>

ViewOneViewModel

public class ViewOneViewModel : ViewModelBase
    {
        // this doesn't help
        public static readonly DependencyProperty TestStringProperty =
        DependencyProperty.Register("TestString", typeof(string), typeof(MainWindowViewModel), new PropertyMetadata(null));
    }

1 Ответ

0 голосов
/ 26 апреля 2020

Я полагаю, что ваша проблема заключается здесь:

    <TextBlock Text="{Binding Path=TestString, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Foreground="Black"/>

Binding Path=TestString вместо этого должно быть Binding Path=DataContext.TestString, поскольку RelativeSource теперь смотрит на окно, а не на модель окна.

...