2(或更多)ComboBoxes彼此依赖

时间:2010-06-09 10:59:28

标签: silverlight data-binding combobox dependencies

编辑:下面的问题是固定的,在这篇文章中转到EDIT2。

我有一个Organization实体和一个Region实体。组织类型的对象可以有一个或多个连接到它的Region对象,因此我的Region实体中有一个外键到组织实体。使用WCF RIA和实体框架从我的数据库中提取Organization和Region对象。我想将Organization对象放在一个ComboBox中,将Region对象放在另一个ComboBox中,并在选择具有Region对象的ComboBox的组织时自动仅显示连接到所选组织的区域。应该是非常基本的,但我现在设计它的方式根本不起作用。

那么,任何暗示我如何能够实现这个目标?一个简单的简单代码示例非常感谢! (我正在使用SL4,WCF RIA MVVM)

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

使用Venomo的ElemntBinding答案,当我想在我的收藏中添加一个新对象时,这对我来说非常有用,我只是拉动可用的国家和连接区域,然后在文本框中键入一个站点......所以我在我的数据库中获得了组织,区域和站点的组合:)

现在,当我想在我的收藏中编辑网站时,我遇到了一个新问题。在编辑模式下,我希望预先选择和禁用两个下拉菜单(BusinessRule是我可以编辑网站名称,而不是它所连接的组织区域)。因此,通过在Organization combobox上设置SelectedIndex属性,我选择了我的组织,但是当在Regions组合框中执行相同操作时,它会因Object Reference错误而失败。

2 个答案:

答案 0 :(得分:4)

你可以通过一些聪明的ElementBinding来实现这一点。

基本示例:

假设我们有一个像这样的简单类:

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

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

然后,我们将有两个ComboBox es:一个用于选择一个国家,另一个用于选择该国家/地区。当第一个的值发生变化时,第二个应该自我更新。

好的,首先我们必须告诉Silverlight如何显示Country。对于复杂场景,我们可以使用DataTemplate,但就目前而言,我们只需要ComboBox类的DisplayMemberPath属性。

<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的{​​{1}}设置为此集合。

ComboBox

这两个都可以在代码隐藏的构造函数中 好的,现在回到XAML!

我们需要另一个ComboBox以及一种告诉它动态从其他集合中获取其项目的方法 将cbCountries.ItemsSource = countries; 绑定到另一个ItemsSource的所选项目只是实现这一目标的最明显方法。

ComboBox

这应该很简单。

如果您使用MVVM:

您可以从<ComboBox x:Name="cbRegion" ItemsSource="{Binding ElementName=cbCountries, Path=SelectedItem.Regions}"/> 绑定到第一个ItemsSource的{​​{1}}。其余的保持不变。
要告诉ComboBox所选值是什么,请在ViewModel es的ViewModel属性上使用双向绑定,并将其绑定到任何属性在SelectedItem中有它。

如果您的收藏集可以动态更改:

如果国家/地区列表(或您想要使用它的任何内容)可以在运行时更改,则最好为ComboBox类和区域实施ViewModel ,使用INotifyPropertyChanged 如果它不需要在运行时更改,则无需为此烦恼。

答案 1 :(得分: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}" />