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

3

我需要翻译一个接收xaml参数的用户控件:

  <components:MyComponent Sex="MALE"/>

在 MyComponent 控件中,我有一个绑定 ViewModel,如下所示:
<UserControl.DataContext>
    <components:MyComponentViewModel/>
</UserControl.DataContext>

在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();
        }
 }

我的组件视图模型长这样:

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

我希望ViewModel能够知道UserControl中性别(Sex)的值。这是否违背了MVVM模式,或者有一种尊重MVVM的方法可以做到这一点?我该如何实现?


错误的命名。如果属性命名为Sex的DP,必须命名为SexProperty。如果DP命名为SexParamProperty,则属性必须命名为SexParam。然后您可以将其绑定为Sex="{Binding SexInVM}",其中SexInVM是外部ViewModel的属性。 - undefined
它根本不需要MyComponentViewModel - undefined
1个回答

3
为了将控件的值传递给视图模型,通常将控件的属性进行双向绑定。可以声明一个依赖属性,使其默认为双向绑定:
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));

请注意依赖属性标识符字段的约定:<PropertyName>Property
一个控件(无论是UserControl还是其他控件)也不能有自己的私有视图模型对象。它只能公开可绑定属性,这些属性在控件的XAML中被“内部”用作绑定的源属性,例如:
<UserControl x:Class="MyNamspace.MyComponent" ...>
    <Grid>
        <TextBox
            Text="{Binding Sex,
                   RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

该控件不应该设置自己的DataContext,因为像绑定其属性这样的操作将影响到父级元素。
<components:MyComponent Sex="{Binding SexInViewModel}"/>

预期结果无法正常工作。源属性名称是根据当前DataContext解析的,这将是控件的私有视图模型,而不是(预期的)继承的DataContext中的视图模型实例。

另外值得一提的是,像这样的控件没有特定的视图模型类型(或一组属性)的依赖性。因此,它提供了更好的可重用性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接