2016-09-27 6 views
0

내부 UserControl SubView가있는 UserControl MyView가 있습니다.ViewModel을 데이터 바인딩을위한 DependencyProperty로 정의하는 것은 나쁜 습관입니까?

두 개의 UserControls의 뷰 모델은 아래 코드와 같이 내부에 i, e, MyViewModel의 뷰와 동일한 계층 구조를 가지고 있습니다.

public class MyViewModel 
{ 
    private readonly SubViewModel _subViewModel = new SubViewModel(); 

    public SubViewModel SubViewModel { get { return _subViewModel; } } 

    private void HandleSubViewModel() 
    { 
     // Do what is necessary to handle SubViewModel 
    } 
} 

제 질문은 SubViewModel을 SubView에 바인딩하는 방법입니다.

이제 SubView의 코드 숨김에 SubViewModel을 정의하고이를 MyViewModel 클래스의 SubViewModel 속성에 바인딩합니다.

public partial class SubView : UserControl 
{ 
    public static readonly DependencyProperty SubViewModelProperty = DependencyProperty.Register(
    "SubViewModel", typeof (SubViewModel), typeof (SubView), new PropertyMetadata(default(SubViewModel))); 

    public SubViewModel SubViewModel 
    { 
     get { return (SubViewModel) GetValue(SubViewModelProperty); } 
     set { SetValue(SubViewModelProperty, value); } 
    } 
} 

<UserControl x:Class="MyProject.View.MyView" 
      xmlns:parts="clr-namespace:MyProject.View.Parts"> 
    <Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=MyViewModel}"> 
     <parts:SubView SubViewModel="{Binding SubViewModel}"/> 
    </Grid> 
</UserControl> 

이런 식으로 내부 뷰 모델을 바인딩하는 것은 나쁜 습관입니까?

그렇다면 더 나은 방법으로 어떻게 바인딩 할 수 있습니까?

답변

3

왜 좋지 않은가하는 이유 중 하나는 SubViewModel 내부의 속성이 변경되면 MyViewModel이 알 수있는 방법이 없다는 것입니다. 예를 들어 MyViewModel 레벨에서 수행하고 처리해야하는 유효성 검사가 있으면 그렇게 할 수 없습니다.

속성을 변경하면이 문제를 해결할 수 있습니다. SubViewModel에 일정을 올리고 MyViewModel을 구독하고 수신 한 후 적절하게 대응해야합니다.

그 외에도 단점은 없습니다. MVVM and nested view models

MVVM: How to handle interaction between nested ViewModels?

+0

감사하지만 추가 정보를 원하시면 다음 링크를 읽습니까 너를 대단히 너 r 신속한 답변. – user4134476

+0

신속한 답변을 주셔서 대단히 감사합니다. 실제 코드에서'SubViewModel'은'MyViewModel'이'SubViewModel' 속성의 변화를 알 수 있도록'INotifyPropertyChanged'를 구현합니다. – user4134476

+0

예, 왜 안 되니? 'SubViewModel'에서'SubViewModelChanged'와 같은 이벤트를 가지고 있고 속성 변경을 알릴 때마다이 이벤트를 발생 시키십시오. 'MyViewModel'에서이 이벤트에 간단하게 가입하고 그에 따라 행동하십시오. – bit

0

당신은 다음과 같이 수행 할 수 있습니다 : 보기 모델 :

public class MyViewModel 
{ 
    private readonly SubViewModel _subViewModel; 

    public SubViewModel SubViewModel 
    { 
     get { return _subViewModel; } 
    } 

    public MyViewModel() 
    { 
     _subViewModel = new SubViewModel(); 
     _subViewModel.Text1 = "blabla"; 
    } 
} 

public class SubViewModel : DependencyObject 
{ 
    public string Text1 
    { 
     get { return (string)GetValue(Text1Property); } 
     set { SetValue(Text1Property, value); } 
    } 

    public static readonly DependencyProperty Text1Property = 
     DependencyProperty.Register("Text1", typeof(string), typeof(SubViewModel)); 
} 

SubUserControl :

<UserControl x:Class="WpfApplication1.SubUserControl" 
     xmlns= ... > 
<Grid Height="200" Width="300" Background="Aqua"> 
     <TextBlock Text="{Binding SubViewModel.Text1}" /> 
</Grid> 

+0

답을 보내 주셔서 감사합니다.하지만'DependencyObject'가 스레드 선호도를 가지므로'SubViewModel'이'DependencyObject'를 상속하지 못하도록하고 싶습니다. – user4134476

+0

문제 없습니다. SubViewModel.Text1은 종속성 속성 일 필요는 없습니다. INotifypropertyChanged가 구현되면 정상적인 속성이 될 수 있습니다. – GenericTeaCup