I have a simple 2 x View + ViewModel program, that shares some data between the ViewModels, such as Members ObservableCollection. I do this via a Parent MainViewModel. However, every time either of the Views is accessed (via the buttons), it "refreshes" the data, and seems to re-generate the Members ObservableCollection. Both Views can access the Members ObservableCollection, but the data is different. It seems a new "MainViewModel" is being created every time either of the Views are accessed...?
Have I got some program logic wrong? I am trying to create a Parent ViewModel that allows the Child ViewModels/Views to share the same DataCollections. I am not too sure where to set the DataContext for the Child Views...
Thanks for your help!
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>
<DataTemplate DataType="{x:Type local1:MainViewModel}"> <local:MembersView/> </DataTemplate> <DataTemplate DataType="{x:Type local1:MainViewModel}"> <local:WeeksView/> </DataTemplate>
Then the program throws a run-time error "Key is already in dictionary" – Damian