繁体   English   中英

Wpf UserControl和MVVM

[英]Wpf UserControl and MVVM

我正在考虑为我的应用程序编写WPF用户控件。 我在我的应用程序中使用MVVM。

用户控件可能需要可以设置为父视图的依赖项属性。 使用MVVM时,想法是父视图最终会在UserControls DP与Parent View的VM之间创建绑定

需要在View类中创建Dependency Properties ,因为VM不从DependencyObject继承。 这意味着在XAML代码中添加代码。

我想知道你是否可以就使用MVVM开发WPF应用程序时如何设计用户控件提出建议......

案例1:如果您要创建此控件只是为了在您的应用程序中使用,那么您可以继续为它创建一个ViewModel ,但是您不需要创建DP,您的ViewModel可以只实现INotifyPropertyChanged并且您的父Vm可以仍然绑定他们。

在我们的例子中,对于用户控件,我们创建了单独的VM,并且它的实例存在于ParentVM 因此父视图将在其中具有此控件,并将UserControlVM绑定到此控件( ParentVM.UserControlVM ),usercontrol将处理其他绑定。

案例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和依赖属性

UserControl是“MVVM”中“View”的一部分,就像TextBoxListView控件是View的一部分一样。

无论您决定使用MVVM开发自己的UserControl还是用QBASIC编写它(不推荐),只要他们可以通过绑定到DependencyProperty来完成UserControl所需的一切,它就不会破坏UserControl的使用者的MVVM模式。暴露在你的UserControl 即您的UserControl应该公开它所依赖的属性(因此名称)。 一旦你掌握了这个DependencyProperty突然变得非常有意义,你希望他们对你在构造函数中指定的已更改的事件处理程序和默认值有所帮助。

如果您的UserControl在不同的程序集中,我看不出它是如何产生影响的。

这就是说许多人会提倡你使用MVVM模式本身构建你的UserControl ,因为MVVM带来了所有好的理由,例如帮助另一个开发人员查看你的代码。 然而,有些事情根本不可能和/或更难以更复杂且性能更差的黑客攻击XAML这样做 - 我不是在谈论你的花园种类添加用户表单,而是例如处理数千个视觉效果的布局的UserControl 此外,由于您在View中工作,因此希望UserControl的ViewModel与您的应用程序混合在一起!

基本上我说MVVM很好,不在你的View上使用MVVM!

基本上,不是将UserControl的datacontext绑定到userControlViewModel,而是最好在用户控件的第一个子元素上执行此操作。 这样,您在控件中创建的所有引用都将绑定到userControlViewModel,但依赖项属性可以从您要使用UserControl的数据上下文集中设置。

在我的UserControl XAML上,这种模式对我来说非常好用:

<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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM