C# 不使用setter在属性上进行数据绑定
如何将数据绑定到只有getter而没有setter的属性,以便从wpf中的视图模型访问它?我正在使用C# 不使用setter在属性上进行数据绑定,c#,wpf,data-binding,mvvm,C#,Wpf,Data Binding,Mvvm,如何将数据绑定到只有getter而没有setter的属性,以便从wpf中的视图模型访问它?我正在使用PasswordBox并希望将其SecureString属性绑定到ViewModel属性。如何才能做到这一点?在xaml中绑定: <PasswordBox Text="{Binding SecureString, Mode=OneWay}"... ViewModel的使用者应该能够通过该方法设置SecureString。我使用此类和库来访问属性,而无需设置器: public sealed
PasswordBox
并希望将其SecureString
属性绑定到ViewModel属性。如何才能做到这一点?在xaml中绑定:
<PasswordBox Text="{Binding SecureString, Mode=OneWay}"...
ViewModel的使用者应该能够通过该方法设置SecureString
。我使用此类和库来访问属性,而无需设置器:
public sealed class PropertyManager : TriggerAction<FrameworkElement>
{
#region Fields
private bool _bindingUpdating;
private PropertyInfo _currentProperty;
private bool _propertyUpdating;
#endregion
#region Dependency properties
/// <summary>
/// Identifies the <see cref="Binding" /> dependency property.
/// </summary>
public static readonly DependencyProperty BindingProperty =
DependencyProperty.Register("Binding", typeof(object), typeof(PropertyManager),
new PropertyMetadata((o, args) =>
{
var propertyManager = o as PropertyManager;
if (propertyManager == null ||
args.OldValue == args.NewValue) return;
propertyManager.TrySetProperty(args.NewValue);
}));
/// <summary>
/// Identifies the <see cref="SourceProperty" /> dependency property.
/// </summary>
public static readonly DependencyProperty SourcePropertyProperty =
DependencyProperty.Register("SourceProperty", typeof(string), typeof(PropertyManager),
new PropertyMetadata(default(string)));
/// <summary>
/// Binding for property <see cref="SourceProperty" />.
/// </summary>
public object Binding
{
get { return GetValue(BindingProperty); }
set { SetValue(BindingProperty, value); }
}
/// <summary>
/// Name property to bind.
/// </summary>
public string SourceProperty
{
get { return (string)GetValue(SourcePropertyProperty); }
set { SetValue(SourcePropertyProperty, value); }
}
#endregion
#region Methods
/// <summary>
/// Invokes the action.
/// </summary>
/// <param name="parameter">
/// The parameter to the action. If the action does not require a parameter, the parameter may be
/// set to a null reference.
/// </param>
protected override void Invoke(object parameter)
{
TrySetBinding();
}
/// <summary>
/// Tries to set binding value.
/// </summary>
private void TrySetBinding()
{
if (_propertyUpdating) return;
PropertyInfo propertyInfo = GetPropertyInfo();
if (propertyInfo == null) return;
if (!propertyInfo.CanRead)
return;
_bindingUpdating = true;
try
{
Binding = propertyInfo.GetValue(AssociatedObject, null);
}
finally
{
_bindingUpdating = false;
}
}
/// <summary>
/// Tries to set property value.
/// </summary>
private void TrySetProperty(object value)
{
if (_bindingUpdating) return;
PropertyInfo propertyInfo = GetPropertyInfo();
if (propertyInfo == null) return;
if (!propertyInfo.CanWrite)
return;
_propertyUpdating = true;
try
{
propertyInfo.SetValue(AssociatedObject, value, null);
}
finally
{
_propertyUpdating = false;
}
}
private PropertyInfo GetPropertyInfo()
{
if (_currentProperty != null && _currentProperty.Name == SourceProperty)
return _currentProperty;
if (AssociatedObject == null)
throw new NullReferenceException("AssociatedObject is null.");
if (string.IsNullOrEmpty(SourceProperty))
throw new NullReferenceException("SourceProperty is null.");
_currentProperty = AssociatedObject
.GetType()
.GetProperty(SourceProperty);
if (_currentProperty == null)
throw new NullReferenceException("Property not found in associated object, property name: " +
SourceProperty);
return _currentProperty;
}
#endregion
}
您还需要指定将被更新的事件值,在本例中为PasswordChanged
,并指定要绑定的属性,在本例中为Password
:
<PasswordBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PasswordChanged">
<behaviors:PropertyManager
Binding="{Binding Path=MyPasswordProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SourceProperty="Password" />
</i:EventTrigger>
</i:Interaction.Triggers>
</PasswordBox>
此类用途广泛,可与任何属性一起使用,还支持双向绑定。通过将绑定上的设置为“单向”,可以使用
Get only属性进行绑定-
<PasswordBox Text="{Binding SecureString, Mode=OneWay}"
是否要绑定到视图模型上的只读属性?我是wpf和mvvm的新手。我想在我的viewmodel中获取密码的securestring,但不会对其进行设置。您的问题是PasswordBox
控件上的securestring
属性是只读属性,这意味着您不能从标记或代码进行设置。是否要让密码框
从XAML在视图模型上设置类型为SecureString
的属性?阅读了吗?非常好!我不是用这个作为密码箱,但是@Victor Mukherjee在不知情的情况下问了一个很好的问题,你的回答很好。我有点嫉妒,谁写了PropertyManager类?
<PasswordBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PasswordChanged">
<behaviors:PropertyManager
Binding="{Binding Path=MyPasswordProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SourceProperty="Password" />
</i:EventTrigger>
</i:Interaction.Triggers>
</PasswordBox>
<PasswordBox Text="{Binding SecureString, Mode=OneWay}"