2

我正在开发一个 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>

4

3 回答 3

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"
于 2013-03-18T15:30:11.927 回答
2

由于您使用 ViewModel Locator 来设置数据上下文,因此您可以重复使用它来查找属性 CollectionTwo。

您的绑定将如下所示:

<ComboBox ItemsSource="{Binding Path=Main.CollectionTwo, Source={StaticResource Locator}}" />
于 2013-03-18T15:55:26.633 回答
0

ComboBox 绑定相对于 ListItem 的绑定。所以它搜索 CollectionTwo 作为 ClassOne 的一个属性。查看要绑定到的 RelativeSource 或将 CollectionTwo 移动到 ClassOne 类。这样,您可以轻松地为每个 ListViewItem 构建不同的列表。

于 2013-03-18T14:47:26.930 回答