如何绑定到不同于已指定的 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}
我在 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}