2012-03-27 24 views
1

我想在C#中设置自定义属性,以设置业务对象属性是否可编辑,最终启用或禁用ReadOnly XAML中的文本框。由于(我认为)IsEditable已经在System.Windows.Controls中实现,我认为这将工作:用于设置文本框是否可编辑的自定义属性

[AttributeUsage(AttributeTargets.Property)] 
public class EditableAttribute : Attribute 
{ 
    public EditableAttribute(bool isEditable) 
    { 
     this.ReadOnly = !isEditable; 

    } 
    public virtual bool ReadOnly { get; set; } 
} 

嗯,去图,它没有。我将[Editable(false)]设置为对象中的字符串,并且它仍然是可编辑的。我有一种感觉,我甚至没有接近。任何帮助或建议将不胜感激!

我知道这可以设置为xaml中的样式,但对于这种情况它需要在业务对象中。

感谢

回答

1

您可以使用BindingDecoratorBase来使用自定义绑定并使用属性。

以下代码只是我在使用custom validation的项目中修改我的代码。它可能应该折射。

public interface IEditatble 
{ 
    void SetValue(Control sender, DependencyProperty property); 
} 

[AttributeUsage(AttributeTargets.Property)] 
public class EditableAttribute : Attribute, IEditatble 
{ 
    public EditableAttribute(bool isEditable) 
    { 
     this.ReadOnly = !isEditable; 

    } 
    public virtual bool ReadOnly { get; set; } 

    public void SetValue(System.Windows.Controls.Control sender, System.Windows.DependencyProperty property) 
    { 
     sender.SetValue(property, this.ReadOnly); 
    } 
} 

您可以创建自定义绑定:

public class ReadonlyBinding : BindingDecoratorBase 
{ 
    private DependencyProperty _targetProperty = null; 
    public ReadonlyBinding() 
    : base() 
    { 
     Binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
    } 

    public override object ProvideValue(IServiceProvider provider) 
    { 
     // Get the binding expression 
     object bindingExpression = base.ProvideValue(provider); 

     // Bound items 
     DependencyObject targetObject; 

     // Try to get the bound items 
     if (TryGetTargetItems(provider, out targetObject, out _targetProperty)) 
     { 
      if (targetObject is FrameworkElement) 
      { 
       // Get the element and implement datacontext changes 
       FrameworkElement element = targetObject as FrameworkElement; 
       element.DataContextChanged += new DependencyPropertyChangedEventHandler(element_DataContextChanged); 
      } 
     } 

     // Go on with the flow 
     return bindingExpression; 
    } 

    void element_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     object datacontext = e.NewValue; 
     if (datacontext != null && _targetProperty != null) 
     { 
      PropertyInfo property = datacontext.GetType().GetProperty(Binding.Path.Path); 
      if (property != null) 
      { 
       var attribute = property.GetCustomAttributes(true).Where(o => o is IEditatble).FirstOrDefault(); 
       if (attribute != null) 
       {       
        Control cntrl = sender as Control; 
        ((IEditatble)attribute).SetValue(cntrl, _targetProperty); 
       } 

      } 
     } 
    } 
} 

而且你可以用它喜欢:

[Editable(true)] 
public string Name { get; set; } 

的XAML:

<TextBox IsReadOnly="{local:ReadonlyBinding Path=Name}" /> 
1

为了您EditableAttribute工作,文本框类应使用反射你的模型来检查属性是否设置,并设置必要的属性。我想说的是,属性不过是元数据,它不控制应用程序工作流程,除非应用程序希望如此。

您可以从基本的TextBox继承并插入必要的功能,尽管它是一种矫枉过正。您应该只声​​明IsSomePropertyReadOnly变量并将其绑定到TextBox中。

但如果你感觉真的很奇特,你可以写一些包装类,像

public class ReadOrWriteText<T> 
{ 
    private T _value; 
    bool IsReadOnly { get; set; } 

    public T Value 
    { 
     get { return _value; } 
     set { if (IsReadOnly) return; _value = value; } 
    } 
} 

,并绑定到它的IsReadOnly和Value属性。虽然它也是一种矫枉过正。

相关问题