具有MVVM和依赖属性的WPF用户控件地狱

具有MVVM和依赖属性的WPF用户控件地狱,wpf,user-controls,mvvm,dependency-properties,Wpf,User Controls,Mvvm,Dependency Properties,这就是我想做的: 我正在编写一个UserControl,希望其他开发人员使用它 我希望最终用户能够使用依赖属性使用我的控件 <lib:ControlView ControlsText={Binding Path=UsersOwnViewModelText} /> 我使用的是MVVM模式 我正在使用 所以我有两个问题: 如果在XAML中使用一个UserControl,那么当控件的Loaded事件触发时,UserControl必须将ViewModel设置为它的DataCon

这就是我想做的:

  • 我正在编写一个
    UserControl
    ,希望其他开发人员使用它
  • 我希望最终用户能够使用依赖属性使用我的控件

    <lib:ControlView ControlsText={Binding Path=UsersOwnViewModelText} />
    
    
    
  • 我使用的是MVVM模式

  • 我正在使用

    
    
所以我有两个问题:

  • 如果在XAML中使用一个UserControl,那么当控件的
    Loaded
    事件触发时,UserControl必须将ViewModel设置为它的
    DataContext
    ,而不是使用
    方法,这样的想法对吗

  • 如何允许用户将数据绑定到控件的依赖属性,同时仍将数据绑定到我的ViewModel


  • 您应该将这两个用例分开:

  • 其他开发人员将使用的(用户)控件
  • 应用程序将使用的用户控件
  • 重要的是,后者取决于前者,而不是相反

    用例1将使用依赖项属性、模板绑定以及所有用于创建常规WPF控件的内容:

    MyControl.cs:

    public class MyControl : Control
    {
        // dependency properties and other logic
    }
    
    <ControlTemplate Type="local:MyControl">
        <!-- define the default look in here, using template bindings to bind to your d-props -->
    </ControlTemplate>
    
    public class MyViewModel : ViewModel
    {
        // properties and business logic
    }
    
    Generic.xaml:

    public class MyControl : Control
    {
        // dependency properties and other logic
    }
    
    <ControlTemplate Type="local:MyControl">
        <!-- define the default look in here, using template bindings to bind to your d-props -->
    </ControlTemplate>
    
    public class MyViewModel : ViewModel
    {
        // properties and business logic
    }
    
    MyView.xaml:

    <UserControl ...>
        <local:MyControl SomeProperty="{Binding SomePropertyOnViewModel}" .../>
    </UserControl>
    
    
    

    两全其美,完美分离。其他开发人员只依赖于控件,控件可能(也可能应该)位于与视图模型和视图完全不同的程序集中。

    首先,如果您正在开发一个将被其他人使用的用户控件,我认为MVVM不是一个好的选择。无外观控件是您真正应该开发的。耶利米·莫里尔对这一问题有自己的看法

    也就是说,如果您有一个默认的公共构造函数,那么可以使用XAML设置datacontext

    内部ControlView.xaml放置:

    <UserControl.DataContext>
        <local:ControlViewModel />
    </UserControl.DataContext>
    

    A
    UserControl
    是“MVVM”中“视图”的一部分,就像
    TextBox
    ListView
    控件是视图的一部分一样

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

    如果您的
    UserControl
    是否在不同的程序集中,我看不出这有什么区别

    也就是说,许多人会提倡您使用MVVM模式本身构建
    UserControl
    ,因为MVVM带来了很多好的理由,例如帮助其他开发人员查看您的代码。然而,有些事情根本不可能和/或更难更复杂、性能更低——我不是说你的花园式添加用户表单,而是说一个
    UserControl
    处理数千种视觉效果的布局。此外,由于您在视图中工作,因此不希望将
    UserControl
    的视图模型与应用程序混合在一起


    基本上,我是说在MVVM中不在您的视图中使用MVVM是很好的

    基本上,与其将UserControl的datacontext绑定到userControlViewModel,不如在用户控件的第一个子元素上绑定。这样,您在控件内所做的所有引用都将绑定到userControlViewModel,但依赖项属性可以从要使用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>
    

    然后,当您在主视图上使用此选项时,可以使用要传递给MyUSerControl的值设置dependency属性

    谢谢您的回复。我正在创建一个复合控件,想想级联组合框。它接缝有点重,以创建一个控制这种方式为我的需要。谢谢你的回复,因为这仍然是有用的。非常好的模式,谢谢。这没关系,但是如果没有设计的ViewModel,组件就没有意义,那么您需要进行管理。e、 g.在您的ViewModel中,有CollectionViewSource的过滤器或排序项。如果没有viewmodel内部变量移动,其他dep.properties将失去意义。因此,这个问题的答案会根据您的意图而变化。看起来MVVM并不适合创建用户控件。因此,有了这个心理障碍,我就能够解决我的问题。我必须将UserControl中的子控件的DataContext设置为UserControl本身,这意味着消费控件可以为UserControl提供DataContext,从而绑定到我的DependencyProperties。(我想那是对的…)不管怎样,它起作用了,所以我很高兴-1在XAML中将UserControl的viewmodel分配给UserControl的DataContext将破坏尝试使用UserControl的DependencyProperties的父级的绑定。特别是对于OP中的此绑定,它将导致绑定引用UserControl的viewmodel,而不是父对象的viewmodel。唯一的解决方法是让父级知道这一点,并使用ElementName绑定。我认为MVVM对于usercontrol来说是不错的,如果它说goes并从数据库中获取项目列表,并且必须反映在用户控件中的控件中。但是我认为,如果您想直接向控件的使用者公开属性,那么您应该在代码中公开属性,该代码可能会将一些子控件属性转换为与控件相关的数据类型