2

私はComboBoxを備えたリストビューを持っているWinRTアプリケーションに取り組んでいます。ListviewにはItemssourceとして特定のObservableCollectionがあり、ComboBoxのコンテンツを動的に変更できる必要があるため、ComboBoxにはItemsSourceとして別のObservableCollectionが必要です。

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は、たとえば、文字列を持つ各クラスの1つのプロパティです。

ランダムに入力すると長さが異なる可能性があるため、両方のコレクションは分離したままにする必要があります。

EDIT @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

RelativeSourceを使用してリストビューレベルでバインドされているアイテムではなく、ビューモデルを検索するには、データコンテキストで1レベル上に移動する必要があります。

<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のバインディングに関連しています。そのため、ClassOneのプロパティとしてCollectionTwoを検索します。バインドするRelativeSourceを確認するか、CollectionTwoをクラスClassOneに移動します。これにより、ListViewItemごとに異なるリストを簡単に作成できます。

于 2013-03-18T14:47:26.930 に答える