时间:2010-07-26 10:17:11

标签: .net wpf mvvm user-controls dependency-properties

3 个答案:

答案 0 :(得分:26)

答案 1 :(得分:8)

UserControl是" View"的一部分。 in" MVVM"就像TextBoxListView控件是视图的一部分一样。

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

如果你的UserControl在不同的装配中,我看不出它会有什么影响。

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

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

答案 2 :(得分:-1)

基本上,不是将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