WPF 用户控件的多个实例都使用相同的 ViewModel [英] Multiple instances of a WPF user control all use the same ViewModel
问题描述
我有一个应用程序,当我单击一个按钮时,它会加载一个带有 UserControl
的新 TabItem
.这工作正常,但是...当我再次单击添加"按钮时,另一个 TabItem
添加了一个新的 UserControl
实例.问题来了.当我在 tab1 中添加一些数据并切换到 tab2 时,我也会在那里看到输入的数据.这怎么可能?我为每个 UserControl
使用一个新的 ViewModel
,那么 tab1 和 tab2 上的用户控件如何显示相同的数据.它可能会很愚蠢,但我找不到它......
I have an app that when I click a button loads a new TabItem
with a UserControl
. This works fine, but... When I click the Add button again, another TabItem
is added with a new instance of the UserControl
. Here comes the problem.
When I add some data in tab1 and switch to tab2, I also see the entered data there. How is this possible? I use a new ViewModel
for each UserControl
so how can both user controls on tab1 and tab2 show the same data.
It will probably be something stupid, but I can't find it...
结构是这样的:MainWindow
加载一个 UserControl
,上面只有一个 TabControl
.单击菜单中的添加按钮后,将添加一个新的 TabItem
,并在其上添加一个新的 UserControl
.
Structure is like this: MainWindow
loads a UserControl
with only a TabControl
on it.
After clicking an Add button in the menu a new TabItem
is added with a new UserControl
on it.
SO 上有一些看起来像这样但不同的问题.
There are here on SO some issues that look like this but are different.
这是一些代码.
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
有一个保存 TabItems
的 DP:
TabViewModel
has a DP which holds the 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); }
}
加载在 TabItem
、MemberControl.cs
上的 UserControl
:
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;
}
然后最后我菜单上的命令实际上将 MemberControl
添加为 TabControl
上的新 TabItem
:
And then at last the Command on my menu that actually adds the MemberControl
as an new TabItem
on the TabControl
:
private void LoadNewMember(object notUsed)
{
_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
_addOverview.RaiseCanExecuteChanged();
}
我在绑定过程中的某个地方做错了,但如上所述,我找不到它.
Somewhere along the way I do something wrong with the binding, but as said, I can't find it.
感谢您的帮助.
推荐答案
您似乎将每个 MemberControl
的 DataContext 设置了两次.
You appear to be setting the DataContext of each MemberControl
twice.
一旦您将 MemberViewModel
添加到您的选项卡集合中:
Once when you add the MemberViewModel
to your tab collection:
_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
由于您设置了 DataTemplate,这将创建一个 MemberControl
.
this will create a MemberControl
due to the DataTemplate you have set up.
然后,在您的 MemberControl
的构造函数中,您将 DataContext 重置为 MemberViewModel
的新实例:
Then, in your MemberControl
's constructor you then reset the DataContext to a new instance of MemberViewModel
:
public MemberControl()
{
InitializeComponent();
this.DataContext = new MemberViewModel{};
}
由于第二个 new
,我假设您在两个选项卡中都获得了默认值.
I assume you are getting default values in both tabs due to this second new
.
这篇关于WPF 用户控件的多个实例都使用相同的 ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!