2013-03-18 2 views
2

ComboBox가있는 Listview가있는 WinRT 응용 프로그램에서 작업하고 있습니다. Listview에는 ItemSource라는 특정 ObservableCollection이 있습니다. ComboBox에는 ItemsSource와 다른 ObservableCollection이 있어야합니다. 왜냐하면 ComboBox의 내용을 동적으로 변경할 수 있어야하기 때문입니다.WinRT MVVM-Light 콤보 상자가 다른 ItemsSources가있는 ListView에 있음

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> 

및 해당 뷰 모델 :

ClassOne 및 ClassTwo에서
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); 
     } 
    } 

} 

는 예를 들어, 각 클래스에서 하나 명의 재산을 문자열로.

두 컬렉션 모두 무작위로 채울 때 길이가 다를 수 있으므로 별도로 두어야합니다.

편집 @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> 

답변

2

과 같을 것이다.

당신과 같을 것이다 바인딩 :

<ComboBox ItemsSource="{Binding Path=Main.CollectionTwo, Source={StaticResource Locator}}" /> 
+0

고마워요, 이것이 해결책이었습니다! – DrZoidberg

0

바인딩 콤보가의 바인딩을 기준으로이 ListItem. 따라서 ClassOne의 속성으로 CollectionTwo를 검색합니다. RelativeSource에서 CollectionTwo를 바인딩하거나 ClassOne 클래스로 이동하십시오. 그렇게하면 각 ListViewItem에 대해 서로 다른 목록을 쉽게 작성할 수 있습니다.

+0

안녕하세요, 답변 주셔서 감사합니다. 그러나 나는 당신이 설명하려고하는 것을 이해하지 못한다. 나는 학생 프로그래머이므로 모든 것을 이해하지 못합니다. – DrZoidberg

+0

CollectionTwo의 범위는 CollectionOne과 같습니다. 그러나 바인딩은 범위가 CollectionOne의 항목이라고 가정합니다. 즉, XAML은 CollectionTwo를 ClassOne의 속성으로 찾으려고합니다. – Sascha

+0

당신의 대답을 정확하게 이해한다면, 나는 그것이 나의 특정한 프로젝트에서 효과가 있다고 생각하지 않는다.약간의 예를 들어 설명해 주시겠습니까? 감사합니다 – DrZoidberg

2

당신은 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}" /> 

과 같을 것이다 당신이 당신의 데이터 컨텍스트 당신이 속성 CollectionTwo을 찾으려면이 다시 사용할 수 있습니다 설정 뷰 모델 로케이터를 사용하고 있기 때문에 당신의 페이지

<Page x:Name="MyControl" 
+0

하, 내가 답변을 처음으로 끝내기 위해 +1과 똑같은 타이핑했습니다. –

+0

이 답변의 문제점은 AncestorType이 WinRT에서 사용 가능하지 않다는 것입니다. 어쩌면 해결 방법이 있습니까? 그러나 어쨌든 고마워. – DrZoidberg

+0

@DrZoidberg WinRT 시나리오에 맞게 업데이트되었습니다. – Josh

관련 문제