编辑:下面的问题是固定的,在这篇文章中转到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错误而失败。
答案 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}" />