2016-09-27 2 views
0

У меня есть UserControl MyView, у которого есть внутренний SubView UserControl.Неправильная практика определения ViewModel как DependencyProperty для привязки данных?

Модели представления 2 UserControls имеют одинаковую иерархическую структуру с представлениями, i, e, MyViewModel имеет SubViewModel внутри, как показано в приведенном ниже коде.

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.

Теперь я определяю SubViewModel в коде SubView и привязываю его к свойству SubViewModel класса MyViewModel.

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' реализует' INotifyPropertyChanged', так что MyViewModel может знать изменения свойств SubViewModel. – user4134476

+0

Да, почему бы и нет? Имейте событие, подобное 'SubViewModelChanged' в' SubViewModel', и всякий раз, когда вы хотите уведомить об изменении свойства, поднимите это событие. В «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

Благодарим вас за ответ, но я бы хотел запретить 'SubViewModel' унаследовать' DependencyObject', так как 'DependencyObject' имеет сходство потоков. – user4134476

+0

Нет проблем. SubViewModel.Text1 не обязательно должен быть свойством зависимостей. Это может быть нормальным свойством при реализации INotifypropertyChanged. – GenericTeaCup

Смежные вопросы