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

Filed under:

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

Related posts about wpf-binding