Несколько экземпляров пользовательского элемента управления wpf используют одну и ту же модель представления - PullRequest
4 голосов
/ 28 марта 2012

У меня есть приложение, которое, когда я нажимаю кнопку, загружает новый табит с пользовательским контролем.Это работает нормально, но ... Когда я снова нажимаю кнопку Add, добавляется еще один tabitem с новым экземпляром usercontrol.Здесь возникает проблема.Когда я добавляю некоторые данные в tab1 и переключаюсь на tab2, я также вижу введенные данные там.Как это возможно?Я использую новую viewmodel для каждого usercontrol, так как оба usercontrols на tab1 и tab2 могут показывать одни и те же данные.Вероятно, это будет что-то глупое, но я не могу найти это ...

Структура выглядит следующим образом: MainWindow загружает UserControl только с TabControl на нем.После нажатия кнопки «Добавить» в меню добавляется новый табит с новым пользовательским контролем.

Здесь, на SO, есть некоторые проблемы, которые выглядят так, но отличаются ..

Вотнекоторый код.

TabControl.xaml:

<Grid>
<TabControl x:Name="tabControl"
                            ItemsSource="{Binding TabItems}"
                            SelectedIndex="0">
        <TabControl.Resources>
            <DataTemplate DataType="{x:Type ViewModel:OverviewViewModel}">
                <my:OverviewControl />
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModel:MemberViewModel}">
                <my:MemberControl />
            </DataTemplate>
        </TabControl.Resources>
  <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Header"
                                    Value="{Binding Header}" />
                </Style>
  </TabControl.ItemContainerStyle>
</TabControl>
</Grid>

TabControl.cs

public TabControl()
    {
        InitializeComponent();
        this.DataContext = new TabViewModel(true);
    }

В TabViewModel есть DP, который содержит табличные элементы:

        public static readonly DependencyProperty TabItemsProperty = DependencyProperty.Register("TabItems", typeof(ObservableCollection<ITabViewModel>), typeof(TabViewModel), new UIPropertyMetadata(new ObservableCollection<ITabViewModel>()));
    public ObservableCollection<ITabViewModel> TabItems
    {
        get { return (ObservableCollection<ITabViewModel>)GetValue(TabItemsProperty); }
        set { SetValue(TabItemsProperty, value); }
    }

Пользовательский контроль, который загружается на вкладку, MemberControl.cs

public MemberControl()
{
  InitializeComponent();
    this.DataContext = new MemberViewModel{};
}

MemberControlViewModel:

    private MemberModel _memberModel = new MemberModel();

public MemberViewModel()
{
  Address = new AddressViewModel();
}

    public static readonly DependencyProperty FirstNameProperty = DependencyProperty.Register("FirstName", typeof(string), typeof(MemberViewModel), new UIPropertyMetadata(string.Empty, OnFirstNameChanged));
    public string FirstName
    {
        get { return (string)GetValue(FirstNameProperty); }
        set { SetValue(FirstNameProperty, value); }
    }

    public static void OnFirstNameChanged(DependencyObject m, DependencyPropertyChangedEventArgs e)
    {
        var d = m as MemberViewModel;
        if (d._memberModel != null)
            d._memberModel.FirstName = d.FirstName;
    }


    public static readonly DependencyProperty LastNameProperty = DependencyProperty.Register("LastName", typeof(string), typeof(MemberViewModel), new UIPropertyMetadata(string.Empty, OnLastNameChanged));
    public string LastName
    {
        get { return (string)GetValue(LastNameProperty); }
        set { SetValue(LastNameProperty, value); }
    }

    public static void OnLastNameChanged(DependencyObject m, DependencyPropertyChangedEventArgs e)
    {
        var d = m as MemberViewModel;
        if (d._memberModel != null)
            d._memberModel.LastName = d.LastName;
    }
etc...

И, наконец, команда в моем меню, которая фактически добавляет элемент управления какновый tabitem на tabcontrol:

    private void LoadNewMember(object notUsed)
    {
        _tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
        _addOverview.RaiseCanExecuteChanged();
    }

По пути я что-то не так делаю с привязкой, но, как уже было сказано, я не могу ее найти ..

Спасибо за любую помощь.

1 Ответ

3 голосов
/ 28 марта 2012

Вы, кажется, устанавливаете DataContext каждого MemberControl дважды.

Один раз при добавлении MemberViewModel в коллекцию вкладок:

_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });

это создаст MemberControl из-за созданного вами шаблона данных.

Затем в конструкторе MemberControl вы сбрасываете DataContext на новый экземпляр MemberViewModel:

public MemberControl()
{
    InitializeComponent();
    this.DataContext = new MemberViewModel{};
}

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

...