2012-03-27 59 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屬性。雖然它也是一種矯枉過正。

相關問題