2010-06-09 3 views
4

EDIT: проблема под этим исправлена, GO TO EDIT2 в этом сообщении.2 (или больше) ComboBoxes, зависимые друг от друга

У меня есть организация и субъект региона. Объект типа Organization может иметь один или несколько объектов Region, связанных с ним, поэтому у меня есть внешний ключ в моем субъекте Region для организации. Объекты «Организация» и «Регион» извлекаются из моей базы данных с использованием инфраструктуры WCF RIA и сущности. Я хочу поместить объекты организации в один объект ComboBox и Region в другой ComboBox и при выборе органа, имеющего объекты ComboBox для региона, автоматически отображающие только области, которые подключены к выбранной организации. Должно быть довольно простым, но так, как я его разработал прямо сейчас, он вообще не работает.

Итак, любой намек на то, как я могу это достичь? Очень простое прозвище codeexample очень ценится! (я использую SL4, WCF RIA MVVM)

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

Использование ElemntBinding Venomo отвечают теперь это работает отлично подходит для меня, когда я хочу добавить новый объект для моей коллекции, и я просто вытаскиваю доступные страны и связанные регионы, а затем набираю сайт в текстовом поле ... Поэтому я получаю свое сочетание организации, региона и сайта в своей базе данных :)

, У меня возникла новая проблема, когда я хочу изменить сайт в своей коллекции. В режиме EDIT я хочу, чтобы два выпадающих списка были предварительно выбраны и отключены (BusinessRule - это то, что я могу редактировать имя файла, а не какую организацию и регион, к которому он подключен). Поэтому, установив свойство SelectedIndex в Organobox Organization, я выбираю свою организацию, но при выполнении этого же действия в сводке Regions с ошибкой Reference объекта.

+0

Правки может иметь смысл назад, когда этот вопрос был «живой», но в то же время этот вопрос сейчас очень суматоху и сбивает с толку. Можете ли вы переписать содержание, которое здесь, на один, согласованный вопрос? Благодарю. – sarnold

ответ

4

Вы можете достичь этого с помощью некоторых умных ElementBinding.

Простой пример:

Допустим, у нас есть простой класс, как это:

public class Country 
{ 
    public string Name { get; set; } 

    public IEnumerable<string> Regions { get; set; } 
} 

Тогда мы будем иметь два ComboBox эс: один для выбора страны, а другой для выбора региона в этой стране. Второй должен обновиться, когда изменяется значение первого.

Итак, сначала мы должны сообщить Silverlight, как отображать Country. Для сложных сценариев мы могли бы использовать для этого DataTemplate, но пока нам понадобится только свойство DisplayMemberPath класса ComboBox.

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

Таким образом, мы создадим простую коллекцию этих объектов в коде позади:

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", ... 
     }, 
    }, 
    ... 
}; 

Я знаю, что те не все регионы в примерах стран, но это Silverlight пример а не географический урок.

Теперь мы должны установить ItemsSource из ComboBox в этот коллектив.

cbCountries.ItemsSource = countries; 

Оба они могут быть в конструкторе в коде.
Хорошо, теперь вернемся к XAML!

Нам понадобится еще один ComboBox и способ сообщить, что он будет динамически получать свои элементы из другой коллекции.
Привязка его ItemsSource к другому пункту ComboBox - это самый очевидный способ достичь этого.

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

Это должно сделать трюк довольно просто.

Если вы используете MVVM:

Вы можете связываться с ItemsSource первого ComboBox от ViewModel. Остальное остается прежним.
Чтобы сказать, что выбранные значения в ViewModel, используйте Двустороннее привязок на SelectedItem свойстве обоих ComboBox х годов и связывают, что к тому, что имущество у вас есть для этого в ViewModel.

Если ваша коллекция может динамически изменяться:

Если список стран (или независимо от того, что вы хотите использовать это для) может изменяться во время выполнения, то лучше, если вы реализуете INotifyPropertyChanged для Country класс и для регионов, используйте ObservableCollection<>.
Если это не нужно менять во время работы, не нужно беспокоиться об этом.

+0

Venemo, thanx много - я почти там, и я буду отмечать ваше сообщение как ответ. НО, ван, ты смотришь на мое последнее сообщение в этой теме? У меня есть еще один маленький кусочек. – Mcad001

+0

@ Mcad001 - Добро пожаловать. Мне кажется, что вам не хватает атрибута DisplayMemberPath из вашего второго ComboBox. – Venemo

+0

@ Mcad001 - Кстати, StackOverflow не является обычным форумом. Если у вас все еще есть проблемы, не отправляйте ответ (так как это не «реальный» ответ), вместо этого, не стесняйтесь редактировать свой вопрос по мере необходимости. – Venemo

2

вид Модель:

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; 
    } 

В вашем Вид:

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

В вашем примере отсутствует способ сообщить выбранному региону 'ViewModel', а также 'SelectedItem' для первого поля со списком должен быть двусторонним связыванием, чтобы он работал. Кроме того, я не вижу коллекцию 'Organisations' в вашем' ViewModel'. – Venemo

+0

@Venemo: из вопроса, который я предположил, отслеживание выбранного региона не было необходимым, если это так, просто добавьте SelectedRegion в виртуальную машину и атрибут SelectedItem для комбо Regions (это можно легко сделать из Объединение организаций). То же самое происходит с коллекцией Организации (поле со списком уже заполнено, поэтому я предполагаю, что @ Mcad001 уже делает это правильно, я добавил эту часть в VM). Вы правы в отношении способа привязки, я отредактировал ответ, чтобы включить его. – Anero

+0

Хорошо. Теперь ваш ответ правильный.:) – Venemo

Смежные вопросы