WPF 用户控件的多个实例都使用相同的 ViewModel

Pit*_*k76 5 c# wpf mvvm wpf-controls

我有一个应用程序,当我单击一个按钮时,它会加载一个TabItem带有UserControl. 这工作正常,但是......当我再次单击添加按钮时,另一个TabItem添加了UserControl. 问题来了。当我在 tab1 中添加一些数据并切换到 tab2 时,我也会在那里看到输入的数据。这怎么可能?我ViewModel对每个都使用了一个新的,UserControl因此 tab1 和 tab2 上的两个用户控件如何显示相同的数据。它可能会很愚蠢,但我找不到它......

结构是这样的:MainWindow加载一个UserControl只有 a 的 a TabControl。单击菜单中的“添加”按钮后,将添加一个带有新TabItem内容的新UserControl内容。

这里有一些看起来像这样但不同的问题。

这是一些代码。

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>
Run Code Online (Sandbox Code Playgroud)

TabControl.cs

public TabControl()
{
    InitializeComponent();
    this.DataContext = new TabViewModel(true);
}
Run Code Online (Sandbox Code Playgroud)

TabViewModel有一个 DP 持有TabItems

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); }
}
Run Code Online (Sandbox Code Playgroud)

UserControl其被装上TabItemMemberControl.cs

public MemberControl()
{
  InitializeComponent();
    this.DataContext = new MemberViewModel{};
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

然后最后我菜单上的命令实际上将其添加MemberControl为新TabItemTabControl

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

在此过程中的某个地方,我在绑定方面做错了,但如上所述,我找不到它。

谢谢你的帮助。

Gaz*_*yer 4

您似乎将每个 DataContext 设置MemberControl两次。

一旦您将其添加MemberViewModel到选项卡集合中:

_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
Run Code Online (Sandbox Code Playgroud)

这将MemberControl根据您设置的数据模板创建一个。

然后,在 的MemberControl构造函数中将 DataContext 重置为 的新实例MemberViewModel

public MemberControl()
{
    InitializeComponent();
    this.DataContext = new MemberViewModel{};
}
Run Code Online (Sandbox Code Playgroud)

我假设由于第二个原因,您在两个选项卡中都获得了默认值new