简体   繁体   中英

Binding property of MainViewModel to SubView

I'm trying to figure out how to bind a property from my MainWindowViewModel to a ContentControl that is based on another View. RelativeSource Binding seems not to work since the View is in another xaml file? I tried with dependancy property but I didn't understand how to do this correctly I guess.

What I want to achieve here is that when I type in the TextBox of the MainWindow that all 3 views (contentcontrols) also view the updated data. It should be a demo to illustrate that in MVVM the ViewModel can change without knowledge of the Views and different Views react to it.

Sadly RelativeSource Binding and DependancyProperty didn't work for me or I missed a point.

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));
    }

I believe your issue lies here:

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

Binding Path=TestString should instead be Binding Path=DataContext.TestString as the RelativeSource is looking at the window now, not the window's model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM