2014-02-04 3 views
0

В настоящее время я работаю в пользовательском элементе управления WPF с использованием MVVM. Мой MainWindow.xaml выглядит ниже.Как связать свойство в модели представления usercontrol с другим объектом usercontrol

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

И теперь у меня есть два UserControls UserControl1 и UserControl2 каждый имеет текстовое поле , Я хотел бы обновить свойство Text элемента управления textbox в UserControl1 всякий раз, когда будет изменено свойство Text элемента управления Textbox в UserControl2. Для этого я попытался, как показано ниже.

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

} 

UserCon trol2

<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> 

Но это не работает. Кажется, что проблема в теге RelativeSource в UserControl2. Может кто-то помочь в этом.

+0

UserControl1 не является предком UserControl2 ofcourse. Отправьте структуру, в которой вы разместили эти два UserControls в окне. –

+0

У вас есть свойство типа 'UserControl' в вашей модели? Удалите этот тег MVVM ... вы не заслуживаете его использования. – Sheridan

+0

@RohitVats ContentControl в MainWindow.xaml, который я разместил выше, содержит пользовательские элементы управления. Я также опубликовал класс MainWindowModel, где я создал пользовательские элементы управления. Дайте мне знать, если что-то еще нужно. Я опубликовал весь свой код выше. – Rahul

ответ

0

Вы можете использовать свойство зависимостей в своих пользовательских элементах управления, это даст вам свойство, которое можно связать. см link

EDIT 1

Просто был другой взгляд на вашей установке класса. Если вы следуете MVVM подход я не думаю, что вы должны иметь ссылку на ваш пользовательский элемент управления в модели представления

View Модель должна быть больше как

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

Тогда в вашем View

<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 для загрузки различных UserControls в ContentControl

Я не проверял код работает, и вам необходимо будет осуществить INotifyPropertyChanged по всей общественности свойства, поэтому обновление привязок по мере изменения значения свойства.

Надеюсь, что это поможет.

+0

Привязка свойства «SelectedTab.MyUserControlViewModel» дает значения ToString() для ViewModel вместо отображения представления при щелчке по элементу списка. Не могли бы вы объяснить, нет ли здесь чего-то. Исходя из моей первоначальной проблемы, я добавил свойство depedency, как вы предлагали в каждом пользовательском элементе управления, но я не понимаю, как связать свойство зависимостей usercontrol2 со свойством в модели представления usercontrol1. Не могли бы вы объяснить? – Rahul

+0

Теперь я понимаю. Я пропустил определение данных в ресурсах. После того, как вы указали следующее, я смог изменить для завершения шаблона MVVM, как вы предложили. Спасибо за вашу помощь. <локальные: UserControl1 /> Rahul

Смежные вопросы