Подтвердить что ты не робот

Wpf UserControl и MVVM

Я думаю о написании WPF User Control для моего приложения. Я использую MVVM в своем приложении.

Пользовательский элемент управления может потребовать свойства зависимостей, которые могут быть установлены в моем родительском представлении. при использовании MVVM идея состоит в том, что Parent View в конечном итоге создаст привязку между UserControls DP и VM с родительским представлением)

Dependency Properties необходимо создать в классе View, поскольку VM не наследует от DependencyObject. Это означает добавление кода в код XAML позади.

Мне было интересно, можете ли вы дать советы относительно того, как я должен создавать пользовательский элемент управления при разработке приложения WPF с использованием MVVM...

4b9b3361

Ответ 1

Случай 1: Если вы создаете этот элемент управления только для использования в приложении, вы можете создать для него ViewModel, но вам не нужно создавать DP, ваша ViewModel может просто реализовать INotifyPropertyChanged а ваш родительский Vm может по-прежнему привязывать к ним.

В нашем случае для пользовательских элементов управления мы создали отдельную виртуальную ParentVM и ее экземпляр присутствовал в ParentVM. Таким образом, родительское представление будет иметь этот элемент управления и будет связывать UserControlVM с этим UserControlVM управления (ParentVM.UserControlVM), а ParentVM.UserControlVM позаботится о других привязках.

Случай 2. Если ваш элемент управления будет использоваться другими приложениями/разработчиками, и вы не хотите, чтобы он был простым, продолжайте создавать пользовательские элементы управления после реализации шаблона элемента управления. Таким образом, вы можете создавать элементы управления без внешнего вида и использовать dependency properties. Более того, тот, кто использует этот элемент управления, не должен знать о связанной модели представления и использовать ее.

Некоторые из подобных вопросов/сообщений:

Вопрос о дизайне WPF (пользовательский элемент управления или mvvm): Вопрос о дизайне WPF (пользовательский элемент управления или mvvm)

Пользовательский элемент управления в WPF с использованием концепции MVVM: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6293b176-e1e9-4610-af49-d53e6d294969/

Ад пользовательского управления WPF с MVVM и свойствами зависимости: ад пользовательского управления WPF с MVVM и свойствами зависимости

Ответ 2

A UserControl является частью "View" в "MVVM", так же как элементы управления TextBox или ListView являются частью представления.

Если вы решите использовать MVVM для разработки своего UserControl или записать его в QBASIC (не рекомендуется), он не нарушит шаблон MVVM для потребителей вашего UserControl, если они могут делать все, что им нужно с помощью UserControl, привязав к DependencyProperty, выставленному на вашем UserControl. т.е. ваш UserControl должен показывать свойства, от которых он зависит (отсюда и название). Как только вы поймете, этот DependencyProperty внезапно приобретет большой смысл, и вы хотите, чтобы они были полезны для измененных обработчиков событий и значений по умолчанию, которые вы указываете в своем конструкторе.

Если ваш UserControl находится в другой сборке или нет, я не вижу, как это имеет значение.

Тем не менее многие будут выступать за то, чтобы вы создали свой UserControl с использованием шаблона MVVM для всех хороших причин, связанных с MVVM, например. помогая другому разработчику смотреть на ваш код. Однако некоторые вещи просто невозможны и/или намного сложнее и менее эффективны, взломав XAML, чтобы сделать это - я не говорю о вашем садовом разнообразии. Добавить пользовательскую форму, но, например, UserControl обрабатывает макет тысяч визуальных эффектов. Кроме того, поскольку вы работаете в своем представлении, вы НЕ хотите, чтобы ваши тэги UserControl ViewModels смешивались с вашими приложениями!

В основном я говорю, что в MVVM хорошо использовать MVVM на вашем представлении!

Ответ 3

По сути, вместо привязки вашего текста данных UserControl к userControlViewModel лучше сделать это на первом дочернем элементе пользовательского элемента управления. Таким образом, все ссылки, которые вы делаете в элементе управления, будут связаны с userControlViewModel, но свойства зависимостей могут быть установлены из набора данных контекста, где вы хотите использовать свой UserControl.

Этот шаблон хорошо сработал для меня на вашем XAML UserControl:

<UserControl x:Class="Six_Barca_Main_Interface.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Six_Barca_Main_Interface"
             xmlns:System="clr-namespace:System;assembly=mscorlib" 
             mc:Ignorable="d" 
             d:DesignHeight="900" d:DesignWidth="900">

    <DockPanel  x:Name="rootDock" >
        <TextBlock>{Binding SomethingInMyUserControlViewModel}</TabControl>
    </DockPanel>
</UserControl>

Тогда на код позади:

public partial class MyUserControl : UserControl
{
    UserControlViewModel _vm;

    public MyUserControl()
    {
        InitializeComponent();

        //internal viewModel set to the first child of MyUserControl
         rootDock.DataContext = new UserControlViewModel();

        _vm = (UserControlViewModel)rootDock.DataContext;    

        //sets control to be able to use the viewmodel elements

     }

     #region Dependency properties 
     public string textSetFromApplication
     {
         get{return (string)GetValue(textSetFromApplicationProperty);}
         set{SetValue(textSetFromApplicationProperty, value);}
     }

     public static readonly DependencyProperty textSetFromApplicationProperty = DependencyProperty.Register("textSetFromApplication", typeof(string), typeof(MyUserControl), new PropertyMetadata(null, OnDependencyPropertyChanged));

     private static void  OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
        ((MyUserControl)d)._vm.SomethingInMyUserControlViewModel = 
             e.NewValue as string;
     }
     #endregion