简体   繁体   English

如何使用 MVVM 将 UserControl 参数传递给 ViewModel

[英]How to pass a UserControl parameter to the ViewModel using MVVM

I have a UserControl that receives a parameter form the xaml like this:我有一个 UserControl,它接收来自 xaml 的参数,如下所示:

  <components:MyComponent Sex="MALE"/>

In the MyComponent control I have a ViewModel binded like this:在 MyComponent 控件中,我绑定了一个 ViewModel,如下所示:

<UserControl.DataContext>
    <components:MyComponentViewModel/>
</UserControl.DataContext>

Also in MyComponent code behind looks like this:同样在 MyComponent 后面的代码看起来是这样的:

 public partial class MyComponent: UserControl
 {
        public string Sex
        {
            get => (string)GetValue(SexParamProperty);
            set { SetValue(SexParamProperty, value); }
        }

        public static readonly DependencyProperty SexParamProperty = DependencyProperty.Register(nameof(Sex), typeof(string), typeof(MyComponent));

        public MyComponent()
        {
            InitializeComponent();
        }
 }

MyComponentViewModel looks like this: MyComponentViewModel 看起来像这样:

public class MyComponentViewModel: ViewModelBase
{
   public string Sex { get; set; }
}

I want the ViewModel to know what the value of Sex from the UserControl is.我希望 ViewModel 知道 UserControl 中 Sex 的值是什么。 Is this agains the MVVM pattern or there is a way to do this respecting MVVM?这是针对 MVVM 模式还是有一种方法可以在尊重 MVVM 的情况下做到这一点? How can I do this?我怎样才能做到这一点?

In order to pass a value from a control to a view model, a property of the control is usually bound two-way.为了将值从控件传递到视图模型,控件的属性通常是双向绑定的。 A dependency property can be declared such that it binds two-way by default:可以声明一个依赖属性,使其默认绑定两种方式:

public string Sex
{
    get => (string)GetValue(SexProperty);
    set => SetValue(SexProperty, value);
}

public static readonly DependencyProperty SexProperty =
    DependencyProperty.Register(
        nameof(Sex), typeof(string), typeof(MyComponent),
        new FrameworkPropertyMetadata(
            null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Note the convention for a dependency property's identifer field: <PropertyName>Property .请注意依赖属性的标识符字段的约定: <PropertyName>Property


A control - be it a UserControl or any other control - must also not have its own private view model object.一个控件——无论是 UserControl 还是任何其他控件——也不能有自己的私有视图模型对象。 It would instead only expose bindable properties that are "internally" used as source properties of Bindings in the control's XAML, eg相反,它只会公开“内部”用作控件 XAML 中 Bindings 源属性的可绑定属性,例如

<UserControl x:Class="MyNamspace.MyComponent" ...>
    <Grid>
        <TextBox
            Text="{Binding Sex,
                   RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

The control must especially not set its own DataContext, because binding its properties like控件尤其不能设置自己的 DataContext,因为绑定它的属性,如

<components:MyComponent Sex="{Binding SexInViewModel}"/>

would not work as expected.不会按预期工作。 The source property name is resolved against the current DataContext, which would be the private view model of the control instead of the (expected) view model instance in the inherited DataContext.源属性名称根据当前 DataContext 进行解析,这将是控件的私有视图模型,而不是继承的 DataContext 中的(预期)视图模型实例。

It is also worth to mention that a control like this does not have a dependency of a specific view model type (or a set of properties).还值得一提的是,像这样的控件没有特定视图模型类型(或一组属性)的依赖项。 It hence provides better reusability.因此,它提供了更好的可重用性。

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

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