如何绑定到不同于已指定的 ItemsSource 的 ListBox 内的源

How to bind to a source inside a ListBox different from the ItemsSource already specified

我在 HubSection 中有一个 ListBox,其项目绑定到通过代码隐藏添加到我的 DefaulViewModel 的 class "players"。 首先,我简单地将一个 TextBox 绑定到 class "players" 的 属性 "PlayerName"。 现在我想添加一个 ComboBox,其中包含一些不属于 class 玩家的项目。

可能吗?我认为在 ComboBox 中定义 ItemsSource 会覆盖 ListBox 的 ItemsSource,但没有任何显示。

整个页面的DataContext定义如下:

DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"

那么HubSection是这样的:

<HubSection x:Name="HubSec1">
        <DataTemplate>                    
            <ListBox x:Name="ListBox1" ItemsSource="{Binding players}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                       <StackPanel>
                            <TextBox Text="{Binding Path=PlayerName, Mode=TwoWay}"/>
                            <ComboBox ItemsSource="{Binding Path=ListOfElements}"/>                                                                                                                                                             
                        </StackPanel>
                     </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </DataTemplate>
</HubSection>

如果我以相同的方式定义 ComboBox 但在 ListBox 之外,它将正确显示 "ListOfElements" 的字符串元素。 但是在这个 ListBox 中,ComboBox 是空的。所以我的猜测是已经为 ListBox 定义了一个 ItemsSource,不可能覆盖它。

我试图定义一个 DataTemplate 但没有成功,但这可能是一个很好的解决方案(但我没有正确进行)

我错过了什么?

编辑: ComboBox 项目是一个 ObservableCollection。它不是 "players" class 的一部分。 下面是我如何将这些元素添加到 DefaultViewModel

 DefaultViewModel.Add("players", players);
 DefaultViewModel.Add("MyItemsList", ListOfElements);

在 Windows 应用程序中创建良好的工作绑定可能有点棘手。一种广泛使用的解决方法是使用 Tag 属性.

<ListBox x:Name="ListBox1" ItemsSource="{Binding players}" Margin="0,184,0,0" Tag="{Binding Path=ListOfElements}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBox Text="{Binding Path=PlayerName, Mode=TwoWay}"/>
                <TextBox Text="{Binding Path=Tag, ElementName=ListBox1}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

绑定到具有特定名称的元素将始终有效。 ListOfElements 应该在 ListBox 的范围内,因此您可以使用 Tag 属性 作为代理。如果您需要绑定多个 属性,您还可以使用虚拟 XAML 元素:

<Border Tag="{Binding ...}" Name="dummy1"/>

您可以向上走可视化树并绑定到祖先数据上下文:

{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

前:

{Binding Path=ListOfItems, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}

这应该会为您提供列表框所具有的数据上下文,因此假设您的 ListOfItems 存在于该数据上下文中。

或者您可以命名您的控件,然后通过元素名称绑定到它的数据上下文:

{Binding ElementName=mySourceElement,Path=ListOfItems}