2012-03-24 6 views
0

WPF/MVVM의 새로운 기능. "MyData"유형의 데이터 개체가 있습니다. 속성 중 하나는 "MySubsetData"유형입니다.UserControl의 ViewModel에 데이터를 가져 오는 방법은 무엇입니까?

나는 DataGrid에 "MyData"개체의 컬렉션을 보여줍니다.

<DataGrid ItemsSource="{Binding Path=MyDataCollection}"> 
    <!-- Each row of the datagrid contains an item of type "MyData" --> 
    <DataGrid.Columns .../> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <local:MySubsetDataUserControl/> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
</DataGrid> 

행 세부 정보에는 "MySubsetData"의 내용이 표시되어야합니다. 행 세부 사항보기는 별도의 사용자 정의 컨트롤 (여기에 "MySubsetDataUserControl")에 있습니다.

현재 "MySubsetDataUserControl"에 대한보기 모델을 설정하지 않으므로 부모의 DataGrid 행에서 데이터 컨텍스트를 상속받습니다. 이 입력해도

<UserControl> 
    <!-- Namespace stuff not shown for simplicity --> 
    <Grid DataContext="{Binding Path=MySubsetData}"> 
     <!-- Show the MySubsetData properties here --> 
     <!-- e.g. a textbox --> 
      <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

내가이 방법으로 몇 가지 문제에 직면하고있다 :

  1. 모든 비즈니스 로직은 사용자 제어 부모의 뷰 모델, 단순히 속하지 않는 될 것이다. 뷰 모델을 필요 이상으로 복잡하게 만듭니다. 사용자 컨트롤의 명령 바인딩이 xaml을 매우 추악하게 보일 수도 있습니다. 그것은 단지 옳다고 생각하지 않습니다.

  2. 동시에 행 세부 정보를 볼 수 있으므로 "MySubsetData"속성을 뷰 모델의 관찰 가능 속성에 바인딩 할 수 없습니다. 나는. 코드 (예 : TextData)에서 속성을 변경하면 변경 사항이보기에 반영되지 않습니다. 내 해결 방법은 "TextData"속성을 변경하지 않는 것입니다. 대신 TextBox Text 속성의 내용을 변경하면 "TextData"속성이 업데이트됩니다. 그리고 그것은 매우 틀린 느낌입니다!

그래서 내 사용자 컨트롤에 다른보기 모델을 사용하고 싶습니다. 그런 다음 내 데이터에 액세스하는 방법을 모르겠습니다.

<UserControl.DataContext> 
    <local:UserControlViewModel/> 
</UserControl.DataContext> 

"MySubsetData"에 지금 액세스하려면 어떻게해야합니까?

public class ViewModel 
{ 
    public IEnumerable<MyData> MyDataCollection{get; private set;} 
} 

public class MyData 
{ 
    public MySubsetData MySubsetData { get; } 
} 

는 데이터 그리드를 포함한 귀하의보기

<UserControl.DataContext> 
    <local:ViewModel> 
</UserControl.DataContext> 

<DataGrid ItemsSource="{Binding Path=MyDataCollection}"> 
    <DataGrid.Columns .../> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <!-- each row of the items control has an implicit DataContext of MyData --> 
      <!-- so bind the DataContext of the subset control to MySubsetData --> 
      <local:MySubsetDataUserControl DataContext={Binding MySubsetData}/> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
</DataGrid> 

은 이제 일부 컨트롤이 같이 볼 수있을 것입니다 :

답변

0

하자는이 같은 뷰 모델을 가지고 가정

<UserControl> 
    <Grid> 
     <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

질문을 다시 읽으면, 내가 한 모든 질문은 Xaml을 약간 다른 방식으로 반복하는 것일 수도 있습니다.

그러나 다양한 클래스가 INotifyPropertyChanged를 구현해야합니다.

public class MySubsetData : INotifyPropertyChanged 
{ 
    public string TextData 
    { 
     get{...} 
     set{...; OnPropertyChanged("TextData"); } 
    } 
} 

그런 다음 TextData 속성에 바인딩 된 TextBox는 코드의 변경 내용을 반영합니다.

+0

대답은 내 설정을 올바르게 설명합니다. 그게 내가 현재하고있는 일이다. 사용자 컨트롤 그리드에서 호출하는 동안 호출 자체에서 사용자 정의 컨텍스트를 설정하기 만하면됩니다.네가 좀 더 우아하지만 내 질문에 답하지 않아. – UdoG

+0

'코드에서 속성 (예 : TextData)을 변경하면 변경 사항이보기에 반영되지 않습니다.'라고 말합니다. 뷰 모델이 INotifyPropertyChanged를 구현하고 TextData 속성이 OnPropertyChanged ("TextData")를 발생시키는 경우 반영됩니다. – Phil

+0

그게 정확히 포인트입니다. 두 행 세부 정보가 표시되어 있다고 가정 해 보겠습니다. 한 행에 "MyData1.MySubsetData.TextData"가 표시됩니다. 다른 하나는 "MyData2.MySubsetData.TextData"를 표시합니다. 따라서 데이터 그리드 뷰 모델은 관찰 가능한 단일 TextData 속성을 가질 수 없습니다. 아니면 내 실수가 여기 있니? – UdoG

관련 문제