使用Catel将View Property映射到ViewModel

时间:2015-07-16 01:12:00

标签: view mapping viewmodel catel

我正在进行登录视图。问题是PasswordBox无法绑定到视图模型,因此我将视图的属性映射到viewmodel。

这是视图

public partial class LoginView : MetroDataWindow
{
    /// <summary>
    /// Initializes a new instance of the <see cref="LoginView"/> class.
    /// </summary>
    public LoginView()
        : this(null) { }

    /// <summary>
    /// Initializes a new instance of the <see cref="LoginView"/> class.
    /// </summary>
    /// <param name="viewModel">The view model to inject.</param>
    /// <remarks>
    /// This constructor can be used to use view-model injection.
    /// </remarks>
    public LoginView(LoginViewModel viewModel)
        : base(viewModel)
    {
        InitializeComponent();
    }

    [ViewToViewModel(MappingType = ViewToViewModelMappingType.ViewToViewModel)]
    public SecureString Contrasena
    {
        get { return (SecureString)GetValue(ContrasenaPropiedad); }
        set { SetValue(ContrasenaPropiedad, value); }
    }

    // Using a DependencyProperty as the backing store for MapCenter.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ContrasenaPropiedad = DependencyProperty.Register("Contrasena", typeof(SecureString),
        typeof(LoginView), new PropertyMetadata(null, (sender, e) => ((LoginView)sender).UpdateContrasena()));

    private void UpdateContrasena()
    {
        MessageBox.Show("VIEW: FirstName changed to " + ContrasenaPropiedad.ToString());
    }

    private void tbPassword_PasswordChanged(object sender, RoutedEventArgs e)
    {
        Contrasena = tbPassword.SecurePassword;

    }

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);

        if (e.Property == ContrasenaPropiedad)
        {
            int i = 0;
        }
    }
}

这是具有属性

的viewmodel部分
public static readonly PropertyData ContrasenaPropiedad = RegisterProperty("Contrasena", typeof(SecureString), null, (sender, e) => ((LoginViewModel)sender).OnContrasenaChange());

    public void OnContrasenaChange()
    {
        _messageService.Show("VIEW MODEL: FirstName changed to " + Contrasena.ToString());
    }

    public SecureString  Contrasena
    {
        get
        {
            return GetValue<SecureString >(ContrasenaPropiedad);
        }
        set
        {
            SetValue(ContrasenaPropiedad, value);
        }
    }

viewmodel的onChange函数永远不会触发。

我将此代码基于此问题的最后一条评论中给出的示例

Catel ViewToViewModel attribute

但它不起作用。我是否遗漏了某些内容,或者评论中的错误从未修复过?

此外,由于视图是唯一一个更改属性的视图,我应该使用ViewToViewModelMappingType.ViewToViewModel类型吗?它以任何方式改变了映射的实现吗?

1 个答案:

答案 0 :(得分:1)

密码是一种特殊的品种。但是Catel有一个针对该问题的解决方案,UpdateBindingOnPasswordChanged行为:

<PasswordBox>
   <i:Interaction.Behaviors>
         <catel:UpdateBindingOnPasswordChanged Password="{Binding Password, Mode=TwoWay}" />
   </i:Interaction.Behaviors>
</PasswordBox>

PS。你知道Catel.Fody吗?它使您的代码更易读,更容易编写。