2010-10-18 8 views
5

मेरे आवेदन में मेरे पास संख्यात्मक (डबल या int) ViewModel गुण हैं जो टेक्स्टबॉक्स से बंधे हैं। ViewModel IDataErrorInfo को यह सुनिश्चित करने के लिए लागू करता है कि 'व्यापार तर्क' के लिए स्वीकार्य श्रेणियों के भीतर दर्ज मूल्यों में गिरावट आती है (उदा। ऊंचाई नकारात्मक मान नहीं हो सकती है)। मेरे पास प्रति पृष्ठ कई टेक्स्टबॉक्स हैं और एक बटन है (एक विज़ार्ड में 'अगली' सोचें) सक्षम गुण एक व्यूमोडेल बूलियन से जुड़ा हुआ है जो निर्दिष्ट करता है कि पूरे पृष्ठ पर कोई त्रुटि है या नहीं। मेरे द्वारा लिखे गए IDataErrorInfo नियमों के अनुसार बटन की सक्षम/अक्षम स्थिति वैध/अमान्य मानों के साथ ठीक से अपडेट की गई है।ValidatesOnExceptions इनपुट त्रुटियों के ViewModel को सूचित करना

हालांकि, मेरे व्यूमोडेल को यह पता करने का कोई तरीका नहीं है कि एक अपवाद फेंक दिया गया है क्योंकि इनपुट मान परिवर्तित नहीं होता है (यानी "12bd39" मान्य डबल नहीं है) और परिणामस्वरूप रूपांतरण अपवादों के मामले में खराब इनपुट के बावजूद 'अगला' बटन सक्षम रहेगा।

<TextBox Text="{Binding Temperature, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/> 

मैं कैसे दृश्य दे सकते हैं पता है कि एक 'ValidatesOnExceptions' शैली त्रुटि हुई है: जीयूआई लेकिन ठीक से क्योंकि मेरे बंधन का एक adorner साथ त्रुटि को दर्शाता है। जोश स्मिथ का here प्रत्येक व्यू मॉडेल प्रॉपर्टी को एक स्ट्रिंग बनाने और अपनी अपवाद जांच को रोल करने पर निर्भर करता है जो बहुत सारे अतिरिक्त काम की तरह लगता है। मैं अतिरिक्त कार्ल Shifflett के कार्यान्वयन here में देख शुरू किया, लेकिन मैं कराई घटना मैं उम्मीद होती है जब दृश्य के codebehind फ़ाइल में इस कोड को डालने पर कब्जा नहीं कर पा रहे:

public ViewClass() 
{ 
this.InitializeComponent(); 
     this.AddHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(ValidationErrorHandler)); 
} 

private void ValidationErrorHandler(object sender, RoutedEventArgs e) 
{ 
    var blah = e as System.Windows.Controls.ValidationErrorEventArgs; 
    if (blah.Action == ValidationErrorEventAction.Added) 
    { 
    } 
    else if (blah.Action == ValidationErrorEventAction.Removed) 
    {  
    } 
} 

सिल्वरलाइट एक घटना है कि आप भी सदस्यता ले सकते हैं प्रतीत होता है , लेकिन मुझे डब्ल्यूपीएफ (3.5) में सटीक समतुल्य नहीं मिल रहा है। किसी भी मदद की सराहना की है!

+0

शायद यह वैकल्पिक दृष्टिकोण आपके लिए काम करेगा: http://stackoverflow.com/questions/921601/how-can-i-handle-a- अवैधता-error-in-my-viewmodel-instead-of-my- विचार-कोड-व्यवहार – Ragepotato

+0

अपने दृश्य-मॉडल में रूटेड घटनाओं को हुक अप करने और पीछे कोड से बचने के लिए यह कभी भी अच्छा विचार नहीं है कि मैं जोश स्मिथ का समाधान सुझाता हूं। यदि आप चीजों को "साफ" रखना चाहते हैं तो IDataErrorInfo इंटरफ़ेस जाने का तरीका है। –

+0

मैं सहमत हूं। स्क्रैच से एक नई परियोजना शुरू करते समय मैं निश्चित रूप से जोश स्मिथ के समाधान पर जाऊंगा। दुर्भाग्यवश इस मामले में ऐसा करने के लिए मुझे बहुत ही कम समय सीमा के तहत 30 दृश्य मॉडल को दोबारा करने की आवश्यकता होगी। – astonish

उत्तर

3

मैं देखें कि Validation.ErrorEvent का सदस्य बनता के लिए एक आधार वर्ग घटना

public class MVVMViewBase : UserControl 
    { 
     private RoutedEventHandler _errorEventRoutedEventHandler; 
     public MVVMViewBase() 
     { 
      Loaded += (s, e) => 
       { 
        _errorEventRoutedEventHandler = new RoutedEventHandler(ExceptionValidationErrorHandler); 
        AddHandler(Validation.ErrorEvent, _errorEventRoutedEventHandler); 
       }; 

      Unloaded += (s, e) => 
       { 
        if (_errorEventRoutedEventHandler != null) 
        { 
         RemoveHandler(Validation.ErrorEvent, _errorEventRoutedEventHandler); 
         _errorEventRoutedEventHandler = null; 
        } 
       }; 
     } 

     private void ExceptionValidationErrorHandler(object sender, RoutedEventArgs e) 
     { 
      ValidationErrorEventArgs args = (ValidationErrorEventArgs) e; 
      if (!(args.Error.RuleInError is IUiValidation)) return; 

      DataErrorInfoViewModelBase viewModelBase = DataContext as DataErrorInfoViewModelBase; 
      if(viewModelBase == null) return; 

      BindingExpression bindingExpression = (BindingExpression) args.Error.BindingInError; 
      string dataItemName = bindingExpression.DataItem.ToString(); 
      string propertyName = bindingExpression.ParentBinding.Path.Path; 

      e.Handled = true; 
      if(args.Action == ValidationErrorEventAction.Removed) 
      { 
       viewModelBase.RemoveUIValidationError(new UiValidationError(dataItemName, propertyName, null)); 
       return; 
      } 

      string validationErrorText = string.Empty; 
      foreach(ValidationError validationError in Validation.GetErrors((DependencyObject) args.OriginalSource)) 
      { 
       if (validationError.RuleInError is IUiValidation) 
       { 
        validationErrorText = validationError.ErrorContent.ToString(); 
       } 
      } 
      viewModelBase.AddUIValidationError(new UiValidationError(dataItemName, propertyName, validationErrorText)); 
     } 
    } 

और ViewModel = DataErrorInfoViewModelBase के लिए एक आधार वर्ग कि AddUIValidationError और RemoveUIValidationError

द्वारा सूचित किया जाता

इसके अलावा सभी कराई है मेरे प्रमाणीकरण नियम वर्ग IUiValidation को कार्यान्वित करते हैं जिसका उपयोग केवल यूआई त्रुटियों के प्रचार (कोई सदस्य नहीं) के हिस्से के रूप में कक्षा को चिह्नित करने के लिए किया जाता है। (आप एक ही उद्देश्य के लिए एक विशेषता का उपयोग कर सकते हैं)।

संबंधित मुद्दे