2016-08-10 86 views
1

我有一個CSLA對象具有兩個託管屬性和一個自定義Attribute。 要求是至少有一個屬性爲空。wpf錯誤提供程序不刷新

換句話說: 如果將屬性A設置爲某物並且屬性B已具有值,則屬性A和B將變爲無效。在消隱財產B後,財產A應該變爲有效,反之亦然。

爲解決此問題,我在屬性設置器中調用Validator.ValidateProperty以在設置B時驗證屬性A,反之亦然。

問題是錯誤提供程序未更新。當屬性A的值和屬性得到更新時,錯誤提供程序出現在兩個框的周圍,這非常好。當消隱屬性A時,即使我在屬性A設置後觸發了屬性B的驗證,錯誤提供程序也會離開txtBoxA並停留在txtBoxB附近。請注意第二個我嘗試修改屬性B錯誤提供程序消失。我看起來像我沒有正確調用驗證的方式。

這個問題令我瘋狂。我不確定我做錯了什麼。

C#

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 


     class CustomAttribute : ValidationAttribute 
     { 
     private readonly string _other; 
     public CustomAttribute(string other) 
      { 
      _other = other; 
      } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
      { 
      var property = validationContext.ObjectType.GetProperty(_other); 
      if (property == null) 
       { 
       return new ValidationResult(
        string.Format("Unknown property: {0}", _other) 
       ); 
       } 
      var otherValue = property.GetValue(validationContext.ObjectInstance, null); 

      if (!String.IsNullOrEmpty(value.ToString()) && !String.IsNullOrEmpty(otherValue.ToString())) 
       { 

       return new ValidationResult("At least on property has to be null !"); 
       } 
      return null; 
      } 
     } 




     public class Example : BusinessBase<Example> 
     { 
      public static PropertyInfo<string> AProperty = RegisterProperty<String>(p => p.A); 
     [CustomAttribute("B")] 
     public string A 
      { 
      get { return GetProperty(AProperty); } 
      set { SetProperty(AProperty, value); 

      if (B != "") 
        { 
        try 
         { 
         Validator.ValidateProperty(B, new ValidationContext(this) { MemberName = "B" }); 
         } 
        catch (Exception) 
         { 


         } 

        } 
       } 

      } 
     public static readonly PropertyInfo<string> BProperty = RegisterProperty<String>(p => p.B); 
     [CustomAttribute("A")] 
     public string B 
      { 
      get { return GetProperty(BProperty); } 
      set { SetProperty(BProperty, value); 

       if (A != "") 
        { 
        try 
         { 
         Validator.ValidateProperty(A, new ValidationContext(this) { MemberName = "A" }); 
         } 
        catch (Exception) 
         { 


         } 

        } 

       } 
      } 
     } 

WPF#

<TextBox Name="txtBoxA" Width="300" Text="{Binding A, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" /> 
<TextBox Name="txtBoxB" Width="300" Text="{Binding B, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" /> 

回答

1

我通過創建自定義CSLABusinessRule解決的問題。使兩個屬性相互依賴。

添加了此方法的業務對象類示例#

using Csla; 
using Csla.Rules; 
using System; 
using System.ComponentModel.DataAnnotations; 

protected override void AddBusinessRules() 
{ 
BusinessRules.AddRule(new CustomBusinessRule(AProperty)); 
BusinessRules.AddRule(new CustomBusinessRule(BProperty)); 
BusinessRules.AddRule(new Csla.Rules.CommonRules.Dependency(AProperty, BProperty)); 
BusinessRules.AddRule(new Csla.Rules.CommonRules.Dependency(BProperty, AProperty)); 

} 

創建自定義規則

using System; 
using System.Collections.Generic; 
using Csla.Rules; 

public class CustomBusinessRule : BusinessRule 
     { 
     public OnlyOneOutPutLocationBusinessRule(Csla.Core.IPropertyInfo primaryProperty) : base(primaryProperty) 
      { 
      InputProperties = new List<Csla.Core.IPropertyInfo> { primaryProperty }; 
      } 
     protected override void Execute(RuleContext context) 
      { 
      Example target = (Example)context.Target; 
      if (!string.IsNullOrEmpty(ReadProperty(target, Example.A).ToString()) && !String.IsNullOrEmpty(ReadProperty(target, Example.B).ToString())) 
       { 
       context.AddErrorResult("At least on property has to be null !"); 

       } 
      } 
     }