Master Details and collectionViewSource in separate views cannot make it work.
Posted
by devnet247
on Stack Overflow
See other posts from Stack Overflow
or by devnet247
Published on 2010-05-24T11:55:22Z
Indexed on
2010/05/24
12:01 UTC
Read the original article
Hit count: 466
wpf-binding
Hi all,
I really cannot seem to make/understand how it works with separate views
It all works fine if a bundle all together in a single window. I have a list of Countries-Cities-etc... When you select a country it should load it's cities.
Works
So I bind 3 listboxes successfully using collection sources and no codebehind more or less (just code to set the datacontext and selectionChanged). you can download the project here
http://cid-9db5ae91a2948485.skydrive.live.com/self.aspx/PublicFolder/2MasterDetails.zip
<Window.Resources>
<CollectionViewSource Source="{Binding}" x:Key="cvsCountryList"/>
<CollectionViewSource Source="{Binding Source={StaticResource cvsCountryList},Path=Cities}" x:Key="cvsCityList"/>
<CollectionViewSource Source="{Binding Source={StaticResource cvsCityList},Path=Hotels}" x:Key="cvsHotelList"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Countries"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="Cities"/>
<TextBlock Grid.Column="2" Grid.Row="0" Text="Hotels"/>
<ListBox Grid.Column="0" Grid.Row="1" Name="lstCountries"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource cvsCountryList}}"
DisplayMemberPath="Name" SelectionChanged="OnSelectionChanged"/>
<ListBox Grid.Column="1" Grid.Row="1" Name="lstCities"
IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource cvsCityList}}"
DisplayMemberPath="Name" SelectionChanged="OnSelectionChanged"/>
<ListBox Grid.Column="2" Grid.Row="1" Name="lstHotels"
ItemsSource="{Binding Source={StaticResource cvsHotelList}}"
DisplayMemberPath="Name" SelectionChanged="OnSelectionChanged"/>
</Grid>
Does not work
I am trying to implement the same using a view for each eg(LeftSideMasterControl -RightSideDetailsControls) However I cannot seem to make them bind. Can you help? I would be very grateful so that I can understand how you communicate between userControls
You can download the project here.
http://cid-9db5ae91a2948485.skydrive.live.com/self.aspx/PublicFolder/2MasterDetails.zip
I have as follows LeftSideMasterControl.xaml
<Grid>
<ListBox Name="lstCountries"
SelectionChanged="OnSelectionChanged"
DisplayMemberPath="Name"
ItemsSource="{Binding Countries}"/>
</Grid>
RightViewDetailsControl.xaml
MainView.xaml
<CollectionViewSource Source="{Binding}" x:Key="cvsCountryList"/>
<CollectionViewSource Source="{Binding Source={StaticResource cvsCountryList},Path=Cities}" x:Key="cvsCityList"/>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Views:LeftViewMasterControl x:Name="leftSide" Margin="5" Content="{Binding Source=}"/>
<GridSplitter Grid.Column="0" Grid.Row="0" Background="LightGray"/>
<Views:RightViewDetailsControl Grid.Column="1" x:Name="RightSide" Margin="5"/>
</Grid>
ViewModels
public class CountryListVM : ViewModelBase
{
public CountryListVM()
{
Countries = new ObservableCollection<CountryVM>();
}
public ObservableCollection<CountryVM> Countries { get; set; }
private RelayCommand _loadCountriesCommand;
public ICommand LoadCountriesCommand
{
get
{
return _loadCountriesCommand ?? (_loadCountriesCommand =
new RelayCommand(x => LoadCountries(), x => CanLoadCountries));
}
}
private static bool CanLoadCountries
{
get { return true; }
}
private void LoadCountries()
{
var countryList = Repository.GetCountries();
foreach (var country in countryList)
{
Countries.Add(new CountryVM { Name = country.Name });
}
}
}
public class CountryVM : ViewModelBase
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public class CityListVM : ViewModelBase
{
private CountryVM _selectedCountry;
public CityListVM(CountryVM country)
{
SelectedCountry = country;
Cities = new ObservableCollection<CityVM>();
}
public ObservableCollection<CityVM> Cities { get; set; }
public CountryVM SelectedCountry
{
get { return _selectedCountry; }
set
{
_selectedCountry = value;
OnPropertyChanged("SelectedCountry");
}
}
private RelayCommand _loadCitiesCommand;
public ICommand LoadCitiesCommand
{
get
{
return _loadCitiesCommand ?? (_loadCitiesCommand =
new RelayCommand(x => LoadCities(), x => CanLoadCities));
}
}
private static bool CanLoadCities
{
get { return true; }
}
private void LoadCities()
{
var cities = Repository.GetCities(SelectedCountry.Name);
foreach (var city in cities)
{
Cities.Add(new CityVM() { Name = city.Name });
}
}
}
public class CityVM : ViewModelBase
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
}
Models
=========
public class Country
{
public Country()
{
Cities = new ObservableCollection<City>();
}
public string Name { get; set; }
public ObservableCollection<City> Cities { get; set; }
}
public class City
{
public City()
{
Hotels = new ObservableCollection<Hotel>();
}
public string Name { get; set; }
public ObservableCollection<Hotel> Hotels { get; set; }
}
public class Hotel
{
public string Name { get; set; }
}
© Stack Overflow or respective owner