I have this really simple MVVM code made with Prism:
- 2 Models (Person, Company - common interface IContact) with 2 ViewModels (Prism) and 2 Views (UserControl)
- 1 ViewModel (collection of interface IContact) with 1 View (ListBox bound to the collection and a ContentControl bound to ListBox's SelectedItem with DataTemplateSelector that returns one of the two UserControls based on the type of the SelectedItem)
How can I pass the Model object (either Person or Company) from the ListBox's SelectedItem (IContact) to one of the two ViewModels (either PersonViewModel or CompanyViewModel) that match the View returned by the DataTemplateSelector (either PersonView or CompanyView)?
Thank you!
There is a lot of code, but it is really simple:
I have these Model classes:
public interface IContact
{
string Address { get; set; }
}
public class Person : IContact
{
public string Address { get; set; }
}
public class Company : IContact
{
public string Address { get; set; }
}
I have these ViewModel classes:
public class ContactViewModel : Prism.Mvvm.BindableBase
{
private ObservableCollection<IContact> _contacts = new ObservableCollection<IContact>();
public ObservableCollection<IContact> Contacts
{
get { return _contacts; }
set { SetProperty(ref _contacts, value); }
}
}
public class PersonViewModel : Prism.Mvvm.BindableBase
{
private Person _person; // I want to set this from the ListBox's SelectedItem
public Person Person
{
get { return _person; }
set { SetProperty(ref _person, value); }
}
}
public class CompanyViewModel : Prism.Mvvm.BindableBase
{
private Company _company; // I want to set this from the ListBox's SelectedItem
public Company Company
{
get { return _company; }
set { SetProperty(ref _company, value); }
}
}
I have these View classes:
<UserControl x:Class="ContactView"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<UserControl.Resources>
<DataTemplate x:Key="PersonDataTemplate">
<local:PersonView>
// How can I pass the SelectedItem to the ViewModel of this UserControl?
</local:PersonView>
</DataTemplate>
<DataTemplate x:Key="CompanyDataTemplate">
<local:CompanyView>
// How can I pass the SelectedItem to the ViewModel of this UserControl?
</local:CompanyView>
</DataTemplate>
<dataTemplateSelectors:contactDataTemplateSelector x:Key="templateSelector"
PersonDataTemplate="{StaticResource PersonDataTemplate}"
CompanyDataTemplate="{StaticResource CompanyDataTemplate}"/>
</UserControl.Resources>
<Grid>
// RowDefinitions here
<ListBox ItemsSource="{Binding Contacts}" x:Name="myListBox">
// ItemTemplate here
</ListBox>
<ContentControl Grid.Row="1"
Content="{Binding ElementName=myListBox, Path=SelectedItem}"
ContentTemplateSelector="{StaticResource templateSelector}" />
</Grid>
</UserControl>
Person:
<UserControl x:Class="PersonView"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<Grid>
<TextBlock Text="{Binding Person.Address}" />
</Grid>
</UserControl>
Company:
<UserControl x:Class="CompanyView"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<Grid>
<TextBlock Text="{Binding Company.Address}" />
</Grid>
</UserControl>
And this:
public class ContactDataTemplateSelector : DataTemplateSelector
{
public DataTemplate PersonDataTemplate { get; set; }
public DataTemplate CompanyDataTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is Person)
{
return PersonDataTemplate;
}
if (item is Company)
{
return CompanyDataTemplate;
}
}
}
ContactViewModel
class - that would be a very simple binding to a property. My goal is to pass the selected item from theContactViewModel
to eitherPersonViewModel
orCompanyViewModel
trough theContentControl
viaDataTemplateSelector
that returns eitherPersonView
orCompanyView
. – Jinjinov