使用 Catel 将视图 属性 映射到 ViewModel
Mapping View Property to ViewModel using Catel
我正在进行登录视图。问题是 PasswordBox 无法绑定到视图模型,因此我将视图的 属性 映射到视图模型。
这是视图
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;
}
}
}
这是带有 属性
的视图模型部分
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 类型吗?它会以任何方式改变映射的实现吗?
密码是一种特殊的品种。但是 Catel 有解决这个问题的方法,UpdateBindingOnPasswordChanged 行为:
<PasswordBox>
<i:Interaction.Behaviors>
<catel:UpdateBindingOnPasswordChanged Password="{Binding Password, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</PasswordBox>
ps。你知道 Catel.Fody 吗?它使您的代码更易读,更易于编写。
我正在进行登录视图。问题是 PasswordBox 无法绑定到视图模型,因此我将视图的 属性 映射到视图模型。
这是视图
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;
}
}
}
这是带有 属性
的视图模型部分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 类型吗?它会以任何方式改变映射的实现吗?
密码是一种特殊的品种。但是 Catel 有解决这个问题的方法,UpdateBindingOnPasswordChanged 行为:
<PasswordBox>
<i:Interaction.Behaviors>
<catel:UpdateBindingOnPasswordChanged Password="{Binding Password, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</PasswordBox>
ps。你知道 Catel.Fody 吗?它使您的代码更易读,更易于编写。