gpt4 book ai didi

c# - 没有 setter 的属性的数据绑定(bind)

转载 作者:行者123 更新时间:2023-11-30 12:46:59 25 4
gpt4 key购买 nike

如何将数据绑定(bind)到只有 getter 而没有 setter 的属性,以便从 wpf 中的 View 模型访问它?我正在使用 PasswordBox 并希望将其 SecureString 属性绑定(bind)到 ViewModel 属性。我该怎么做?

最佳答案

我使用这个类和 System.Windows.Interactivity访问没有 setter 的属性的库:

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
}

要在 XAML 中使用此类,您需要添加对 System.Windows.Interactivity 库的引用并添加此命名空间:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:YOUR NAMESPACE WHERE YOU PUT THE PropertyManager CLASS"

您还需要指定将更新值的事件,在本例中为 PasswordChanged 并指定要绑定(bind)的属性,在本例中为 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>

这个类是通用的,可以与任何属性一起工作,还支持双向绑定(bind)。

关于c# - 没有 setter 的属性的数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18043877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com