2 (or more) ComboBoxes dependent on each other

EDIT: The problem underneath is fixed, GO TO EDIT2 in this post.

I have an organization and a Region object. An object of type Organization can have one or more Region objects associated with it, so I have a foreign key in my Region subject for the organization. The Organization and Region objects are retrieved from my database using the WCF RIA infrastructure and entity. I want to put organization objects in one ComboBox and Region object in another ComboBox, and when I select an authority that has ComboBox objects for a region that automatically display only the areas that are connected to the selected organization. It should be pretty simple, but the way I developed it right now, it doesn't work at all.

So, any hint on how I can achieve this? The very simple nickname codeexample is much appreciated! (I am using SL4, WCF RIA MVVM)

EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2 EDIT2:

Using the Venomo ElemntBinding answer, this works great for me now, when I want to add a new object to my collection, and I just pull out the available countries and related areas, and then type the site in the text box ... So I get my combination of Organization, Region and the site in my database :)

Now I have a new problem when I want to CHANGE the site in my collection. In EDIT mode, I want the two drop-down lists to be pre-selected and disabled (BusinessRule is that I can edit the file name and not which organization it is connected to). Therefore, by setting the SelectedIndex property in the Organobox Organization, I select my organization, but when I perform the same action in the Regions summary with a Reference object error.

+4
source share
2 answers

You can achieve this with some clever ElementBinding s.

Basic example:

Say we have a simple class:

 public class Country { public string Name { get; set; } public IEnumerable<string> Regions { get; set; } } 

Then we will have two ComboBox es: one for choosing a country and the other for choosing a region in this country. The second should be updated when the value of the first changes.

Ok, first we have to tell Silverlight how to display the Country . For complex scenarios, we could use a DataTemplate for this, but for this we only need the DisplayMemberPath property of the ComboBox class.

 <ComboBox x:Name="cbCountries" DisplayMemberPath="Name"/> 

So, we are creating a simple collection of these objects in the code behind:

 var countries = new List<Country>() { new Country { Name = "USA", Regions = new List<string> { "Texas", "New York", "Florida", ... }, }, new Country { Name = "UK", Regions = new List<string> { "Scotland", "Wales", "England", ... }, }, ... }; 

I know that these are not all regions in the sample countries, but this is a Silverlight example, not a geographic lesson.

Now we need to set the ItemsSource from ComboBox to this collection.

 cbCountries.ItemsSource = countries; 

Both of them can be in the constructor in the code. Ok, back to XAML!

We will need another ComboBox and a way to report that it will dynamically retrieve its elements from another collection.
Binding its ItemsSource to another ComboBox is the most obvious way to achieve this.

 <ComboBox x:Name="cbRegion" ItemsSource="{Binding ElementName=cbCountries, Path=SelectedItem.Regions}"/> 

That should make the trick pretty simple.

If you are using MVVM:

You can bind to the ItemsSource first ComboBox from ViewModel . The rest remains the same.
To find out what values ​​are selected for the ViewModel , use the two-way bindings in the SelectedItem property of both ComboBox es, and associate this with any property that you have for it in the ViewModel .

If your collection can change dynamically:

If the list of countries (or what you want to use for this) can change at run time, it is best to implement INotifyPropertyChanged for the Country class and for the regions, use ObservableCollection<> .
If this does not need to be changed at run time, there is no need to worry about it.

+4
source

View Model:

 public ObservableCollection<Organisation> Organisations { get; set; } private Organisation selectedOrganisation; public Organisation SelectedOrganisation { get { return this.selectedOrganisation; } set { if (this.selectedOrganisation != value) { this.selectedOrganisation = value; this.NotifyPropertyChanged("SelectedOrganisation"); this.UpdateRegions(); } } private IEnumerable<Region> regions; public IEnumerable<Region> Regions { get { return this.regions; } set { if (this.regions != value) { this.regions = value; this.NotifyPropertyChanged("Regions"); } } } private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } private void UpdateRegions() { // If regions are not pre-populated you might need to perform a new call to // the service that retrieves organisations in order to retrieve the associated Regions entities // for the SelectedOrganisation organisation this.Regions = this.SelectedOrganisation.Regions; } 

In your view:

 <ComboBox x:Name="Organisations" ItemsSource="{Binding Organisations}" SelectedItem="{Binding SelectedOrganisation, Mode=TwoWay}" /> <ComboBox x:Name="Regions" ItemsSource="{Binding Regions}" /> 
+2
source

Source: https://habr.com/ru/post/1312313/


All Articles