如何将usercontrol的视图模型中的属性绑定到另一个usercontrol中的属性

时间:2014-02-04 15:25:25

标签: c# wpf xaml mvvm user-controls

我目前正在使用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中文本框控件的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标记存在问题。有人可以帮忙吗。

1 个答案:

答案 0 :(得分:0)

您可以在用户控件上使用依赖项属性,这将为您提供可绑定属性。见link

编辑1

再看看你的班级设置。如果您遵循MVVM方法,我认为您不应该在视图模型中引用您的用户控件

View Model应该更像

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>

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

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

我没有对代码进行测试,您需要在所有公共属性上实现INotifyPropertyChanged,以便在更改属性值时更新绑定。

希望有所帮助。

相关问题