2012-03-21 13 views
11

पर सत्यापन बाध्यकारी मैं अभी भी WPF में सत्यापन के साथ संघर्ष कर रहा हूं।प्रथम लोड

मेरे पास एक कस्टम सत्यापन नियम है जिसके लिए पाठ को टेक्स्टबॉक्स में दिखने की आवश्यकता है यानी यह अनिवार्य क्षेत्र की बाधा को लागू करता है।

<TextBox local:Masking.Mask="^[a-zA-Z0-9]*$" x:Name="CameraIdCodeTextBox" Grid.Row="1" Grid.Column="1"> 
    <Binding Path="CameraIdCode" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True" ValidatesOnExceptions="True"> 
    <Binding.ValidationRules> 
     <localValidation:RequiredFieldRule /> 
    </Binding.ValidationRules> 
    </Binding> 
</TextBox> 

समस्या है, कि खिड़की के पहली बार लोड, वहाँ पाठ बॉक्स में कोई पाठ है जब (आप उम्मीद करेंगे के रूप में)। लेकिन टेक्स्ट प्रॉपर्टी को व्यूमोडेल पर किसी संपत्ति के लिए बाध्य किया जा रहा है, और इस तरह, सत्यापन नियम फायरिंग है, यह दर्शाता है कि विंडो के साथ कोई समस्या है - इससे पहले कि उपयोगकर्ता को व्यवसाय नियम का उल्लंघन करने का मौका भी मिला हो।

क्या यह एक समस्या है जिसे हल किया गया है? मैं इसका अनुभव करने वाला पहला नहीं रहा हूं। मुझे यकीन है कि यह युवा खिलाड़ियों के लिए एक जाल है।

+0

क्या आप कोशिश कर सकते हैं ... UpdateSourceTrigger = "LostFocus" –

+0

आप एक सत्यापन समूह बनाने में सक्षम हो सकते हैं, और केवल इसे सक्षम कर सकते हैं, जब उपयोगकर्ता पहले कुछ फ़ील्ड में बदलाव करता है। –

+0

@AngelWPF मैंने कोशिश की है। खिड़की लोड होने पर यह अभी भी प्रारंभिक बांध पर मान्य है। – onefootswill

उत्तर

0

यह एक समय हो गया है और मैं इस सवाल को अद्यतन किया जाना चाहिए। मैं एक वर्ग जो मैं इयान Griffths (एक ओ रेली पुस्तक) द्वारा एक WPF किताब में का उपयोग कर इसका समाधान नहीं:

<TextBox local:Masking.Mask="^[0-9]*$" IsEnabled="{Binding Path=LocationNumberEnabled}" Grid.Row="1" Grid.Column="3"> 
    <Binding Path="LocationNumber" Mode="TwoWay" UpdateSourceTrigger="LostFocus" NotifyOnValidationError="True" ValidatesOnExceptions="True"> 
     <Binding.ValidationRules> 
      <localValidation:PositiveNumberRule /> 
      <localValidation:RequiredFieldRule /> 
     </Binding.ValidationRules> 
    </Binding>      
</TextBox> 

:

public static class Validator 
{ 
    /// <summary> 
    /// This method forces WPF to validate the child controls of the control passed in as a parameter. 
    /// </summary> 
    /// <param name="parent">Type: DependencyObject. The control which is the descendent root control to validate.</param> 
    /// <returns>Type: bool. The validation result</returns> 
    public static bool IsValid(DependencyObject parent) 
    { 
     // Validate all the bindings on the parent 
     bool valid = true; 
     LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); 
     while (localValues.MoveNext()) 
     { 
      LocalValueEntry entry = localValues.Current; 
      if (BindingOperations.IsDataBound(parent, entry.Property)) 
      { 
       Binding binding = BindingOperations.GetBinding(parent, entry.Property); 
       foreach (ValidationRule rule in binding.ValidationRules) 
       { 
        ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null); 
        if (!result.IsValid) 
        { 
         BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property); 
         Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null)); 
         valid = false; 
        } 
       } 
      } 
     } 

     // Validate all the bindings on the children 
     for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(parent, i); 
      if (!IsValid(child)) 
      { 
       valid = false; 
      } 
     } 

     return valid; 
    } 

} 

फिर, दृश्य पर, मैं निम्नलिखित विन्यास था एक जादू की तरह काम किया! जब भी मैं मैन्युअल रूप से प्रमाणित करना चाहता था, मैंने बस इस्वालिड विधि को बुलाया एक बटन प्रेस पर।

0

इसके लिए कुछ पैटर्न हैं। मैं आम तौर पर कक्षा/मॉडल ISupportInitialize इंटरफ़ेस पर लागू करता हूं, जिसके लिए आपको BeginInit() और EndInit() बनाने की आवश्यकता होगी, उन तरीकों से मैंने बस एक निजी बूल _isInitializing को सही या गलत पर सेट किया है।

दृश्य मॉडल में

या जहां/जब आप बनाने/पॉप्युलेट अपने मॉडल/वर्ग लपेट यह शुरू के साथ और अंत init:

var o = new SampleObject(); 
o.BeginInit() 
o.StartDate = DateTime.Now; //just some sample property... 
o.EndInit(); 

तो फिर निर्भर करता है कि कैसे अपने ValidationRule शुरू हो जाती है, तो आप के राज्य की जांच कर सकता यह देखने के लिए कि आपको मान्य करने की आवश्यकता है या नहीं, _isInitializing। विशेषता

हाल ही में मैंने प्रयोग कर रहे सत्यापनकर्ताओं PropertyChanged पर जो आग ताकि आप की तरह कुछ कर सकता है:

[CustomValidator("ValidateStartDate")] 
public DateTime StartDate 
{ get ... 
{ 
    set 
    { 
     if(_startDate == value) return; 
     _startDate = value; 
     if(_isInitializing) return; 
     RaisePropertyChange(() => StartDate); 
     }.. 

आप ISupportInitialize से परेशान नहीं करना चाहते हैं, तो सभी मूल्यों है कि आप में जरूरत से पारित निर्माण के दौरान आपकी संपत्ति संपत्ति नहीं है। पहली बार गुण आप पर ही टिककर खेल क्वेरी करेगा बाइंडिंग और उनके मान मिल जाएगा, और कुछ भी करने के बाद संपत्ति सेटर के माध्यम से जाना होगा और मान्य हो:

//c-tor 
public MyObject(DateTime start) 
{ 
    _startDate = start; 
} 
संबंधित मुद्दे