【问题标题】:How to pass a UserControl parameter to the ViewModel using MVVM如何使用 MVVM 将 UserControl 参数传递给 ViewModel
【发布时间】:2020-08-26 20:02:43
【问题描述】:

我有一个 UserControl,它接收来自 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();
        }
 }

MyComponentViewModel 如下所示:

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

我希望 ViewModel 知道 UserControl 中 Sex 的值是什么。这是违反 MVVM 模式还是有办法做到这一点尊重 MVVM?我该怎么做?

【问题讨论】:

  • 命名错误。如果 Poeporty 命名为Sex DP 必须命名为SexProperty。如果 DP 命名为 SexParamProperty,则属性必须命名为 SexParam。然后你可以绑定它Sex="{Binding SexInVM}",其中SexInVM是外部ViewModel的属性。
  • ...它根本不需要MyComponentViewModel

标签: c# wpf mvvm


【解决方案1】:

为了将值从控件传递到视图模型,控件的属性通常是双向绑定的。可以声明依赖属性,使其默认绑定双向:

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));

注意依赖属性的标识符字段的约定:&lt;PropertyName&gt;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 中的(预期)视图模型实例。

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

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 2020-01-27
    • 2011-05-06
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多