c# – 没有setter的属性上的DataBinding
发布时间:2020-12-15 21:54:29 所属栏目:百科 来源:网络整理
导读:如何将数据绑定到只有getter的属性,而没有setter从wpf中的视图模型访问它?我正在使用PasswordBox并希望将其SecureString属性绑定到ViewModel属性.我怎样才能做到这一点? 解决方法 我使用这个类和 System.Windows.Interactivity库来访问没有setter的属性:
如何将数据绑定到只有getter的属性,而没有setter从wpf中的视图模型访问它?我正在使用PasswordBox并希望将其SecureString属性绑定到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),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并指定要绑定的属性,在本例中为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> 这个类是通用的,可以与任何属性一起使用,也支持双向绑定. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |