C# WPF用户控件的多个实例都使用相同的ViewModel
我有一个应用程序,当我点击一个按钮时,它会加载一个新的C# WPF用户控件的多个实例都使用相同的ViewModel,c#,wpf,mvvm,wpf-controls,C#,Wpf,Mvvm,Wpf Controls,我有一个应用程序,当我点击一个按钮时,它会加载一个新的TabItem,带有UserControl。这很好,但是。。。当我再次单击Add按钮时,另一个TabItem添加了UserControl的新实例。问题来了。 当我在tab1中添加一些数据并切换到tab2时,我还会在那里看到输入的数据。这怎么可能?我为每个UserControl使用了一个新的ViewModel,因此tab1和tab2上的两个用户控件如何显示相同的数据。 这可能会很愚蠢,但我找不到 结构如下:MainWindow加载一个UserC
TabItem
,带有UserControl
。这很好,但是。。。当我再次单击Add按钮时,另一个TabItem
添加了UserControl
的新实例。问题来了。
当我在tab1中添加一些数据并切换到tab2时,我还会在那里看到输入的数据。这怎么可能?我为每个UserControl
使用了一个新的ViewModel
,因此tab1和tab2上的两个用户控件如何显示相同的数据。
这可能会很愚蠢,但我找不到
结构如下:MainWindow
加载一个UserControl
,其中只有一个TabControl
。
单击菜单中的添加按钮后,将添加一个新的选项卡项
,并在其上添加一个新的用户控件
这里有一些看起来像这样但又不同的问题
这里有一些代码
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>
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); }
}
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;
}
public MemberControl()
{
InitializeComponent();
this.DataContext = new MemberViewModel{};
}
最后,我的菜单上的命令实际添加了成员控件
,作为选项卡控件
上的新选项卡项
:
private void LoadNewMember(object notUsed)
{
_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
_addOverview.RaiseCanExecuteChanged();
}
在这个过程中的某个地方,我做了一些装订错误的事情,但正如我所说的,我找不到它
感谢您的帮助。您似乎在两次设置每个
成员控件的DataContext
将MemberViewModel
添加到选项卡集合时:
_tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" });
由于您设置的数据模板,这将创建一个MemberControl
然后,在MemberControl
的构造函数中,将DataContext重置为MemberViewModel
的新实例:
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;
}
public MemberControl()
{
InitializeComponent();
this.DataContext = new MemberViewModel{};
}
我假设由于这第二个new
的原因,您在两个选项卡中都得到了默认值。实际上,我有一个想法,不知怎么说,这是不正确的,但是如何做到呢?如果我离开这一行'this.DataContext=newmemberviewmodel{};'在MemberControl之外,我认为MemberControl与ViewModel之间没有绑定,还是我错了?谢谢你证实我的怀疑:)你可以省去它。您的DataTemplate已经为您完成了这项工作。一个模板围绕一个数据对象包装一个XAML“视图”,该对象是模板化XAML的DataContext。刚刚测试过这个,它似乎可以工作:)我确信我以前确实尝试过,但它不起作用,但现在似乎可以。我尝试了几件事,所以也许这就是问题所在。。我会再测试一些,让你知道。。谢谢!