2011-01-21 102 views
0

我对WPF有一个相当简单的问题。我已经四处搜索,但没有找到“答案”呢......将ListBox.SelectedItem绑定到一个对象的属性,并将ItemsSource绑定到另一个List对象(不同级别!)

我想做一个2级的数据绑定。简化,我有一个人的一些属性,也有N地址,每种类型和一些邮编(都可以从组合中选择)。

我从服务器获取以下数据:现在

public List<AddressType> AddressTypeList; // catalogue of Address Types 
public List<ZipCode> ZipCodeList; // catalogue of Zip Codes 

public Person Person; // Person object 
public List<Address> PersonAddressList; // Address List for that person (each has AddresType and ZipCode property) 

,我想这个数据绑定到一些控件。于是,我把这些属性为一些自定义的类(比如数据)和主要用户控件的DataContext属性设置为这个对象:

data = new Data();    

data.AddressTypeList = dao.GetAll<AddressType>(); 
data.ZipCodeList = dao.GetAll<ZipCode>(); 
data.Person = dao.GetPerson(); 
data.PersonAddressList = dao.GetPersonAddressList(Person); 

this.DataContext = data; // this == some parent UserControl 

现在,我的地址列表XAML部分看起来是这样的:

<ListBox Name="listBoxAddressList" ItemsSource="{Binding PersonAddressList}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <ComboBox ItemsSource="{Binding AddressTypeList}" SelectedItem="{Binding AddressType}"/> 
       <TextBox Text="{Binding Address}"/> <!-- this works! --> 
       <ComboBox ItemsSource="{Binding ZipCodeList}" SelectedItem="{Binding ZipCode}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

地址属性获取绑定确定,但AddressTypeList和ZipCodeList不包含。这是合乎逻辑的,因为PersonAddress(在PersonAddressList中)没有该属性(它们处于不同的级别!)。我不想将AddressType和ZipCode的整个列表放入每个地址对象中,我希望将它无痛地绑定到“父”或将其传递给XAML中的每个地址列表项对象。

我认为这是一个常见的要求,在一个组合(一个列表)中有一些值的目录,但其中一个被选中,并且该值绑定到另一个对象的属性。这将如何正确完成?

+0

我会为PersonAddress项目创建一个具有必要属性的ViewModel。或者你可以尝试“{绑定路径=(DataContext.AddressTypeList),RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type ListBox}}}”,但我不确定这个解决方案,所以我不会发送是作为答案。 – vorrtex 2011-01-21 09:26:57

+0

我已经遇到了这两种可能的解决方案。我不喜欢第一个,因为我会手动设置,然后在每个人的地址中携带所有可能的AddressType(以及ZipCodes等)......第二个选项(FindAncestor)似乎有点沉重(我猜想背景中有很多反射)。我正在寻找一个优雅的解决方案,但它似乎并不存在... – dabor 2011-01-21 10:21:11

回答

2

编辑2:您也可以尝试设置您的列表作为静态属性,这样你也许能够直接使用类似的绑定:

ItemsSource="{Binding Source={x:Static local:Data.AddressTypeList}}" 

编辑:尝试使用RelativeSource返回原始数据,如下所示:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.AddressTypeList}" SelectedValue="{Binding AddressType}"/> 

另请参见:将SelectedValue绑定到属性,而不是SelectedItem

例如

<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition SharedSizeGroup="A"/> 
        <ColumnDefinition SharedSizeGroup="B"/> 
       </Grid.ColumnDefinitions> 
       <TextBlock Grid.Column="0" Text="{Binding Name}"/> 
       <ComboBox Grid.Column="1" SelectedValue="{Binding Occupation}"> 
        <sys:String>Programmer</sys:String> 
        <sys:String>GUI Designer</sys:String> 
        <sys:String>Coffee Getter</sys:String> 
       </ComboBox> 
      </Grid> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
相关问题