我正在开发一个WinRT应用程序,我有一个带有ComboBox的Listview。 Listview有一个特定的ObservableCollection作为Itemssource,ComboBox应该有另一个ObservableCollection作为ItemsSource,因为我应该能够动态地改变ComboBox的内容。
我正在使用MVVM-Light框架,ObservableCollections填充在ViewModel中并通过数据绑定显示。
我将给你一个示例Xaml代码:
<Page x:Class="MvvmLight2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore"
d:DesignHeight="768"
d:DesignWidth="1366"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Page.Resources>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding CollectionOne}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding StringOne}"></TextBlock>
<ComboBox ItemsSource="{Binding CollectionTwo}" Width="500">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringTwo}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
和对应的ViewModel:
public class MainViewModel : ViewModelBase
{
private readonly IDataService _dataService;
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
CollectionOne = new ObservableCollection<ClassOne>();
for (int i = 0; i < 4; i++)
{
var temp = new ClassOne()
{
StringOne = "String " + i.ToString()
};
CollectionOne.Add(temp);
}
CollectionTwo = new ObservableCollection<ClassTwo>();
CollectionTwo.Add(new ClassTwo("ADV"));
CollectionTwo.Add(new ClassTwo("Wettelijk"));
}
private ObservableCollection<ClassOne> _collectionOne;
public ObservableCollection<ClassOne> CollectionOne
{
get { return _collectionOne; }
set
{
if (_collectionOne == value)
{
return;
}
_collectionOne = value;
RaisePropertyChanged(() => CollectionOne);
}
}
private ObservableCollection<ClassTwo> _collectionTwo;
public ObservableCollection<ClassTwo> CollectionTwo
{
get { return _collectionTwo; }
set
{
if (_collectionTwo == value)
{
return;
}
_collectionTwo = value;
RaisePropertyChanged(() => CollectionTwo);
}
}
}
在ClassOne和ClassTwo中,每个类中只有一个带有字符串的属性。
两个集合都必须保持独立,因为随机填充时它们的长度可能不同。
修改 @Josh我按照你的指示,但它似乎仍然不起作用,这是我的调整:
<Page x:Class="MvvmLight2.MainPage"
x:Name="MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore"
d:DesignHeight="768"
d:DesignWidth="1366"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Page.Resources>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding CollectionOne}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding StringOne}"></TextBlock>
<ComboBox ItemsSource="{Binding ElementName=MyControl, Path=CollectionTwo}" Width="500">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringTwo}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
答案 0 :(得分:2)
您需要在datacontext中向上移动一级以使用RelativeSource搜索视图模型而不是在列表视图级别绑定的项目:
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page}}, Path=CollectionTwo}" />
对于WinRT情况,请使用控件名称:
ElementName=MyControl
而不是按AncestorType搜索,并为页面命名为“MyControl”。它看起来像
<ComboBox ItemsSource="{Binding ElementName=MyControl, Path=DataContext.CollectionTwo}" />
并且您的网页看起来像
<Page x:Name="MyControl"
答案 1 :(得分:2)
由于您使用ViewModel Locator设置datacontext,因此您可以重复使用它来查找属性CollectionTwo。
你的绑定看起来像这样:
<ComboBox ItemsSource="{Binding Path=Main.CollectionTwo, Source={StaticResource Locator}}" />
答案 2 :(得分:0)
ComboBox绑定相对于ListItem的Binding。因此它搜索CollectionTwo作为ClassOne的属性。查看RelativeSource以绑定到CollectionTwo或将其移动到ClassOne类。这样,您可以轻松地为每个ListViewItem构建不同的列表。