繁体   English   中英

如何将一个用户控件的视图模型中的属性绑定到另一个用户控件中的属性

[英]How to bind a property in the view model of a usercontrol to a property in another usercontrol

我目前正在使用MVVM在WPF用户控件中工作。 我的MainWindow.xaml如下所示。

MainWindow.xaml

<Window.Resources>
    <ObjectDataProvider x:Key="TabsList" ObjectType="{x:Type local:MainWindowModel}" MethodName="GetTabs"/>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListBox Grid.Column="0"  ItemsSource="{Binding Source={StaticResource TabsList}}" IsSynchronizedWithCurrentItem="True">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding Path=TabName}" Margin="10"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ContentControl Grid.Column="1" Content="{Binding Source={StaticResource TabsList}, Path=MyUserControl}"/>
</Grid>

数据提供者类如下

public class MainWindowModel
{
    public List<TabInfo> GetTabs()
    {
        return new List<TabInfo>()
        {
            new TabInfo() { TabName="Tab1", MyUserControl = new UserControl1()},
            new TabInfo() { TabName="Tab2", MyUserControl = new UserControl2()}
        };
    }
}
 public class TabInfo
{
    public string TabName { get; set; }
    public UserControl MyUserControl { get; set; }
}

现在,我有两个用户控件UserControl1和UserControl2每个都有一个文本框控件。 每当要更新UserControl2中Textbox控件的Text属性时,我都希望更新UserControl1中textbox控件的Text属性。 为此,我尝试如下。

UserControl1

<UserControl x:Class="MoreOnBinding2.UserControl1"
         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>
    <TextBox Width="200" Height="20" Text="{Binding Path=UserControl1Text}"/>
</Grid>

UserControl1ViewModel

public class UserControl1VM : ViewModelBase
{
    public UserControl1VM()
    {
        this.UserControl1Text = "10";
    }
    private string userControl1Text;

    public string UserControl1Text
    {
        get { return userControl1Text; }
        set
        {
            if (userControl1Text != value)
            {
                userControl1Text = value;
                RaisePropertyChanged(() => UserControl1Text);
            }
        }
    }

}

UserControl2

<UserControl x:Class="MoreOnBinding2.UserControl2"
         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:MoreOnBinding2"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <TextBox Width="200" Height="20" 
        Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:UserControl1}}, 
        UpdateSourceTrigger=PropertyChanged, Path=UserControl1Text}" />
</Grid>

但这是行不通的。 似乎UserControl2的RelativeSource标记中存在问题。 有人可以帮忙吗?

您可以在用户控件上使用Dependency属性,这将为您提供可绑定的属性。 链接

编辑1

只是再看看您的课程设置。 如果您遵循MVVM方法,那么我认为您不应在视图模型中引用用户控件

视图模型应该更像

public Class
{
   ObservableCollection<TabInfo> _Tabs = new ObservableCollection<TabInfo>();
   public ObservableCollection<TabInfo> Tabs
   {
     get{return _Tabs;}
     set {_Tabs = value;}//Need to implement INotifyPropertyChanged [Link][2]
   }

   public TabInfo SelectedTab {get;set;}
}

public class TabInfo
{
    public string TabName { get; set; }
    public UserControlViewModel MyUserControlViewModel{ get; set; }
} 

然后在您看来

<Window.DataContext>
    <vm:MainWindowModel />
</Window.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListBox Grid.Column="0"  ItemsSource="{Binding Tabs}" IsSynchronizedWithCurrentItem="True" SelectedValue="{Binding SelectedTab}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding Path=TabName}" Margin="10"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ContentControl Grid.Column="1" Content="{Binding SelectedTab.MyUserControlViewModel"/>
</Grid>

这应该为您提供一个选项卡列表,然后在选择一个选项卡时,会将ContentControl的内容设置为MyUserControlViewModel。

然后,您需要使用某种模板选择器来控制ContentTemplate,以将不同的UserControl加载到ContentControl中

我尚未测试代码的工作原理,因此您需要在所有公共属性上实现INotifyPropertyChanged,以便在属性值更改时绑定也会更新。

希望有点帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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