Validation support in Silverlight is done via Visual State Manager. All invalid fields have red rectangle around themselves. Unfortunately, this does not work out of the box in IronPython. We have to push it a little bit.
To demonstrate how, I have created a small example. Create a Silverlight app template and change app.py and app.xaml:
C:\IronPython-2.6.1\Silverlight\script\sl.bat python validationapp.py
import clrtype import pyevent from System.Windows import Application from System.Windows.Controls import UserControl from System.ComponentModel import INotifyPropertyChanged, PropertyChangedEventArgs class ValidationClass(INotifyPropertyChanged): __metaclass__ = clrtype.ClrClass PropertyChanged = None def __init__(self, win): self.win = win self._text = 'text' self.PropertyChanged, self._propertyChangedCaller = pyevent.make_event() def add_PropertyChanged(self, value): self.PropertyChanged += value def remove_PropertyChanged(self, value): self.PropertyChanged -= value def OnPropertyChanged(self, propertyName): if self.PropertyChanged is not None: self._propertyChangedCaller(self, PropertyChangedEventArgs(propertyName)) @property @clrtype.accepts() @clrtype.returns(str) def text(self): return self._text @text.setter @clrtype.accepts(str) @clrtype.returns() def text(self, value): if not value.startswith('text'): raise Exception('Value must start with text!') self._text = value self.OnPropertyChanged('text') class App: def __init__(self): self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml") self.root.DataContext = ValidationClass(self.root) App()app.xaml
<UserControl x:Class="System.Windows.Controls.UserControl" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel> <TextBox x:Name="tbValidate1" Width="100" Height="25" Text="{Binding text, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" /> <TextBox Width="100" Height="25" /> <TextBlock Text="{Binding text}" HorizontalAlignment="Center" /> </StackPanel> </UserControl>
When you run this application (C:\IronPython-2.6.1\Silverlight\script\server.bat /d:validation), you'll find out the validation does not work. There is no red rectangle when you enter wrong value; e.g. wrong.
Note the second empty TextBox is there so you can move focus out of the first one to update bound property.
For whatever reason, the invalid component is not switched into invalid state. Could be IronPython bug, could be something else. Anyway to fix it, you have to switch the control into invalid state manually. Add the BindingValidationError event:
from System.Windows import VisualStateManager from System.Windows.Controls import ValidationErrorEventAction ... class App: def __init__(self): self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml") self.root.DataContext = ValidationClass(self.root) self.root.BindingValidationError += self.OnBindingValidationError def OnBindingValidationError(self, sender, event): if event.Action == ValidationErrorEventAction.Added: VisualStateManager.GoToState(event.OriginalSource, 'InvalidUnfocused', True) else: VisualStateManager.GoToState(event.OriginalSource, 'Valid', True
Now when you enter wrong value into TextBox, you can see red rectangle around the control. You also see, the bound variable has the old, correct value text:
You can download the whole source here.
No comments:
Post a Comment