2016-08-10 11 views
1

두 개의 관리 속성과 사용자 지정 Attribute이있는 CSLA 개체가 있습니다. 요구 사항은 하나 이상의 속성이 null 인 것입니다.wpf 오류 공급자가 새로 고침되지 않습니다.

즉, 속성 A가 설정되고 속성 B에 이미 값이 있으면 속성 A와 B가 유효하지 않게됩니다. 속성 B를 비우면 속성 A가 유효하게되고 반대의 경우도 마찬가지입니다.

이 문제를 해결하기 위해 속성 설정자의 Validator.ValidateProperty을 호출하여 B가 설정된 경우 속성 A의 유효성을 검사하고 반대의 경우도 마찬가지입니다.

오류 공급자가 업데이트되지 않는 것이 문제입니다. 속성 A에 값이 있고 속성이 업데이트되면 오류 상자가 두 상자 주위에 표시됩니다. 속성 A를 비우는 경우 오류 공급자가 txtBoxA에서 벗어나 t 속성 A가 설정된 후에 속성 B의 유효성 검사를 트리거했지만 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 내가 정의 CSLABusinessRule를 작성하여 문제를 해결 #

<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

. An은 두 속성을 서로 종속 시켰습니다.

추가 된이 방법은 사용자 정의 규칙을 만든 비즈니스 오브젝트 클래스 예제 #

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 !"); 

       } 
      } 
     }