With input based applications, we often find usage of cascading combo boxes where values of one combobox is dependent on the value selected in another combobox. A typical example is selecting a country from a combo then selecting from a filtered list of cities in a second combobox. This blog shows the same implementation using C1DataGrid for WPF through MVVM pattern. Before we proceed further, lets have a quick look of how our final output would appear.
This section is self understood where you define the Class design for your Business Object Entity. Class structure will define three properties to hold values for the name of a person, country and the associated city. Apart from this, it will hold a list of cities corresponding to the country.
class Person : INotifyPropertyChanged
{
string _pName;
string _country;
string _city;
List _cityList;
public Person()
{
_cityList = new List();
}
public String Name
{
get { return _pName; }
set
{
_pName = value; NotifyPropertyChanged("Name");
}
}
public String Country
{
get { return _country; }
set
{
_country = value;
CityList = LocaltionList.ListOfCities(_country);
NotifyPropertyChanged("Country");
}
}
public String City
{
get { return _city; }
set { _city = value; NotifyPropertyChanged("City"); }
}
public List CityList
{
get { return _cityList; }
set { _cityList = value; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
We will have two more Class structure to hold a list of Countries and their corresponding cities. These classes will be used to get the list of Cities depending on the Country selected for a record.
class Location
{
private string _country;
public String Country
{
get { return _country; }
set { _country = value; }
}
private string _city;
public String City
{
get { return _city; }
set { _city = value; }
}
}
class LocaltionList
{
static List _lstCities;
public static List ListOfCities(string _cn)
{
ObservableCollection _locationList = new ObservableCollection();
_locationList = new ObservableCollection();
_locationList.Add(new Location() { Country = "US", City = "Washington D.C." });
_locationList.Add(new Location() { Country = "US", City = "NewYork" });
_locationList.Add(new Location() { Country = "UK", City = "London" });
_locationList.Add(new Location() { Country = "UK", City = "Birmingham" });
_locationList.Add(new Location() { Country = "India", City = "New Delhi" });
_locationList.Add(new Location() { Country = "India", City = "Mumbai" });
\_lstCities = (from row in \_locationList where row.Country.ToUpper().Equals(_cn.ToUpper()) select row.City).ToList();
_locationList = null;
return _lstCities;
}
}
Once we have the structure for the entities defined, we need to bind it the C1DataGrid ComboBox columns.
<c1:C1DataGrid Name="c1DataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding Items}">
<c1:C1DataGrid.Columns>
<c1:DataGridTextColumn Header="Name" Binding="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<c1:DataGridTemplateColumn Header="Country">
<c1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Country}"/>
</DataTemplate>
</c1:DataGridTemplateColumn.CellTemplate>
<c1:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<c1:C1ComboBox SelectedItem="{Binding Path=Country,Mode=TwoWay}">
<c1:C1ComboBox.Style>
<Style TargetType="c1:C1ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CountryList}"/>
</Style>
</c1:C1ComboBox.Style>
</c1:C1ComboBox>
</DataTemplate>
</c1:DataGridTemplateColumn.CellEditingTemplate>
</c1:DataGridTemplateColumn>
<c1:DataGridTemplateColumn Header="Cities">
<c1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=City}"/>
</DataTemplate>
</c1:DataGridTemplateColumn.CellTemplate>
<c1:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<c1:C1ComboBox SelectedItem="{Binding Path=City,Mode=TwoWay}">
<c1:C1ComboBox.Style>
<Style TargetType="c1:C1ComboBox">
<Setter Property="ItemsSource" Value="{Binding CityList}"/>
</Style>
</c1:C1ComboBox.Style>
</c1:C1ComboBox>
</DataTemplate>
</c1:DataGridTemplateColumn.CellEditingTemplate>
</c1:DataGridTemplateColumn>
</c1:C1DataGrid.Columns>
</c1:C1DataGrid>
Refer to the attached sample for complete implementation. Download Sample