我有一个简单的2 x View + ViewModel程序,它在ViewModel之间共享一些数据,例如 Members ObservableCollection 。我通过父 MainViewModel 执行此操作。但是,每次访问任一视图(通过按钮)时,它都会“刷新”数据,并且似乎重新生成成员ObservableCollection 。两个视图都可以访问Members ObservableCollection,但数据不同。每次访问任何一个视图时,似乎都会创建一个新的“MainViewModel”......?
我的程序逻辑有错吗?我正在尝试创建一个父ViewModel,它允许Child ViewModel / Views共享相同的DataCollections。我不太确定在哪里为子视图设置DataContext ...
感谢您的帮助!
的App.xaml
<Application x:Class="CLM_Scheduler.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CLM_Scheduler"
StartupUri="Views\MainWindow.xaml">
<Application.Resources>
</Application.Resources>
MainWindow.xaml
<Window.DataContext>
<local1:MainViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type local1:MembersViewModel}">
<local:MembersView/>
</DataTemplate>
<DataTemplate DataType="{x:Type local1:WeeksViewModel}">
<local:WeeksView/>
</DataTemplate>
</Window.Resources>
<Grid>
<DockPanel LastChildFill="True">
<StackPanel x:Name="navigation" DockPanel.Dock="Left">
<Button Content="Members" Command="{Binding SelectMembersView}"></Button>
<Button Content="Schedule" Command="{Binding SelectWeeksView}"></Button>
</StackPanel>
<ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}" />
</DockPanel>
</Grid>
MainViewModel.cs
class MainViewModel : ObservableObject
{
private MembersViewModel membersViewModel;
private WeeksViewModel weeksViewModel;
public MainViewModel()
{
membersViewModel = new MembersViewModel();
weeksViewModel = new WeeksViewModel();
}
public MembersViewModel MembersViewModel
{
get { return membersViewModel; }
set { membersViewModel = value; RaisePropertyChanged("MembersViewModel"); }
}
public WeeksViewModel WeeksViewModel
{
get { return weeksViewModel; }
set { weeksViewModel = value; RaisePropertyChanged("WeeksViewModel"); }
}
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set { selectedViewModel = value; RaisePropertyChanged("SelectedViewModel"); }
}
public ICommand SelectMembersView { get { return new RelayCommand(SelectMembersViewExecute, CanSelectMembersViewExecute); } }
void SelectMembersViewExecute()
{
SelectedViewModel = MembersViewModel;
}
bool CanSelectMembersViewExecute() { return true; }
public ICommand SelectWeeksView { get { return new RelayCommand(SelectWeeksViewExecute, CanSelectWeeksViewExecute); } }
void SelectWeeksViewExecute()
{
SelectedViewModel = WeeksViewModel;
}
bool CanSelectWeeksViewExecute() { return true; }
}
MembersViewModel.cs
class MembersViewModel : ObservableObject
{
private Member _SelectedMember;
ObservableCollection<Member> _members = new ObservableCollection<Member>();
public ObservableCollection<Member> Members
{
get{ return _members;}
set
{
_members = value;
RaisePropertyChanged("Members");
}
}
public Member SelectedMember
{
get { return _SelectedMember; }
set { _SelectedMember = value; }
}
public MembersViewModel()
{
for (int i = 0; i < 3; ++i)
{
_members.Add(new Member(_database.GetRandomFirstName, _database.GetRandomLastName));
}
}
void AddMemberExecute()
{
if (_members == null)
return;
_members.Add(new Member(_database.GetRandomFirstName, _database.GetRandomLastName));
}
bool CanAddMemberExecute() {return true;}
public ICommand AddMember { get { return new RelayCommand(AddMemberExecute, CanAddMemberExecute); } }
}
Members.xaml
<UserControl.DataContext>
<local2:MainViewModel />
</UserControl.DataContext>
<Grid>
<Button Grid.Column="0" Grid.Row="1" Content="Add Member" Command="{Binding MembersViewModel.AddMember}" />
<DataGrid Grid.Column="1" Grid.Row="3" ItemsSource="{Binding MembersViewModel.Members}" SelectedItem="{Binding SelectedMember, Mode=TwoWay}" >
</DataGrid>
</Grid>
</UserControl>
Weeks.xaml
<UserControl.DataContext>
<local1:MainViewModel />
</UserControl.DataContext>
<Grid>
<Button Grid.Column="0" Grid.Row="1" Content="Add Member" Command="{Binding MembersViewModel.AddMember}" />
<DataGrid Grid.Column="1" Grid.Row="3" ItemsSource="{Binding MembersViewModel.Members}" SelectedItem="{Binding SelectedMember, Mode=TwoWay}" />
</Grid>
答案 0 :(得分:1)
视图只能有一个DataContext
(视图模型)。每次创建视图时,这会创建一个新的MainViewModel
:
<UserControl.DataContext>
<local1:MainViewModel />
</UserControl.DataContext>
如果你想继承DataContext
的{{1}},你可以像这样绑定它:
MainWindow
你也可以像<UserControl ... DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}">
一样绑定到MainWindowViewModel
的任何属性(不设置UserControl
的{{1}}):
DataContext