WPF ValidationRules disables PropertyChanged - wpf

I have the following textbox that have a propertychanged in the viewmodel.
When I insert the Binding.ValidationRules and I insert some wrong value, it doesn't trigger the propertychanged event and I don't understand why. Any help?
<TextBox Name="RiskCode" HorizontalAlignment="Left" Margin="101.923,8,0,81" TextWrapping="Wrap" Width="56.077" MaxLength="6" Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource textBoxInError}">
<TextBox.Text>
<Binding Path="RiskCode" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<vm:RiskCodeValidation/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

Use ValidationStep.
http://msdn.microsoft.com/en-us/library/system.windows.controls.validationrule.validationstep.aspx
RawProposedValue - Runs the ValidationRule before any conversion occurs.
ConvertedProposedValue - Runs the ValidationRule after the value is converted.
UpdatedValue - Runs the ValidationRule after the source is updated.
CommittedValue - Runs the ValidationRule after the value has been committed to the source.
By default, it's RawProposedValue, which prevents the binding to source from ever occurring - hence your confusion. Use a different option instead:
<Binding.ValidationRules>
<vm:RiskCodeValidation ValidationStep="UpdatedValue" />
</Binding.ValidationRules>

Related

WPF button to update a textbox in xaml with validator

How can I get a button to reset text in a textbox to a known value? In my example the validation rule is triggered so I can't use the button command to update the property, which is good because I don't want the property set if it's not valid. I just want the button to basically reset the value in xaml without involving the property. How would I do that?
<TextBox Grid.Column="1" Grid.Row="9" HorizontalAlignment="Left" Height="20" Width="105" Name="Elevation"
Validation.ErrorTemplate="{StaticResource validationTemplate1}" Style="{StaticResource textBoxInError}">
<TextBox.Text >
<Binding Path="Elevation" Mode="TwoWay" UpdateSourceTrigger="LostFocus">
<Binding.ValidationRules>
<rules:NotEmptyValidationRule ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue"/>
<rules:DoubleValidationRule ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Grid.Column="2" Grid.Row="9" Height="20" Command="{Binding ClickResetCommand}" CommandParameter="Elevation" >R</Button>
Still looking for a XAML solution but for now I've change the button to use OnClick and in the code behind using the following...
case "Elevation":
Elevation.Text = "50";
Validation.ClearInvalid(Elevation.GetBindingExpression(TextBox.TextProperty) ?? throw new InvalidOperationException());
Elevation.Focus();
break;

Getting an "Type must derive from DependencyObject" error, when I try to to set a TargetUpdated event on a DatePicker

I have a XAML DatePicker that is defined as such:
<DatePicker x:Name="startDateDatePicker" Validation.ErrorTemplate="{StaticResource validationTemplate}"
SelectedDateChanged="window_DatePicker_SelectedDateChanged" Validation.Error="ValidationError">
<DatePicker.SelectedDate>
<Binding Path="startDate" Mode="TwoWay" NotifyOnValidationError="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<!-- A couple custom rules. //-->
</Binding.ValidationRules>
</Binding>
</DatePicker.SelectedDate>
</DatePicker>
I need to attach an event handler in my code behind to Binding.TargetUpdated and Binding.SourceUpdated events on the Binding object in my DatePicker.SelectedDate object.
However, when I re-define my tag as such:
<Binding Path="startDate" Mode="TwoWay" NotifyOnValidationError="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged" TargetUpdated="BindingTargetUpdated" SourceUpdated="BindingSourceUpdaed">
I get the error messages:
The attached property "TargetUpdated" can only be applied to types that are derived from "DependencyObject".
and
The attached property "SourceUpdated" can only be applied to types that are derived from "DependencyObject".
What do I need to do to bind to these events? I understand the error message, but I don't know how it relates to the <DatePicker.SelectedDate> item since it should be a DependencyObject.
As mentioned in the comment you need to set event against DatePicker instead of Binding. Also, against the Binding, you need to enable both NotifyOnTargetUpdated and NotifyOnSourceUpdated in order for the events to be raised.
<DatePicker ... TargetUpdated="BindingTargetUpdated" SourceUpdated="BindingSourceUpdaed">
<DatePicker.SelectedDate>
<Binding Path="startDate" ... NotifyOnTargetUpdated="True" NotifyOnSourceUpdated="True">
<Binding.ValidationRules>
<!-- A couple custom rules. //-->
</Binding.ValidationRules>
</Binding>
</DatePicker.SelectedDate>
</DatePicker>

TextBox to PasswordBox in WPF

I have to convert TextBox XAML to PasswordBox XAML. The main problem is <TextBox.Text>.
Any clue how it can be done?
Thank you!
<TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Name="tbxPassword" VerticalAlignment="Top" Width="277">
<TextBox.Text>
<Binding Path="Password" Source="{StaticResource ods}" UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<c:ConfigValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
If its really about password, you should use PasswordBox, Binding it to a dependency property would cause security vulnerabilities.
<PasswordBox
Name="pwdBox"
MaxLength="64"
PasswordChar="#"
PasswordChanged="PasswordChangedHandler"
/>
You can see the basic usage here
Password Box

WPF TextBox control filter + validation

I have TextBox bound to a text property in my window with a validation rule (length is = 4). I needed to add filtering so I took ThomasLebruns WPFDeveloperTools FilteredTextBox. That works but when I use the control I specify each time the Validation.ErrorTemplate and the Binding.ValidationRules - I want to build those into the FilteredTextBox control so they apply automatically to every FilteredTextBox - how to manage that?
Currently I have to:
<Window>
<Grid>
<ps:FilteredTextBox x:Name="textboxPanId" Type="Hex" Grid.Column="1" Grid.Row="1" Height="35" Margin="0,2,0,2" MaxLength="4"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}">
<TextBox.Text>
<Binding Path="pan_id" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ps:PanIdValidation />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</ps:FilteredTextBox>
I would like just:
<ps:FilteredTextBox x:Name="textboxPanId" Type="Hex" Grid.Column="1" Grid.Row="1" Height="35" Margin="0,2,0,2" MaxLength="4">
<TextBox.Text>
<Binding Path="pan_id" UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
but have the error template and validation rule applied. How to move the setting of the Validation.ErrorTemplate and Binding.ValidationRule into resource dictionary with rest of FilteredTextBox xaml?.
<ResourceDictionary>
<ControlTemplate x:Key="TextBoxErrorTemplate">
...
</ControlTemplate>
I think if you create a style for FilteredTextBox in your ResourceDictionary you can set these there, but at least the ErrorTemplate for almost sure.

Silverlight 3 ValidatesOnException not found

I'm trying to add the validation and get the following from the compiler.
The property 'ValidatesOnException' was not found in type 'Binding'.
The property 'ValidatesOnException' does not exist on the type 'Binding' in the XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'.
I tried adding System.Windows.Data in System.Windows as a xmlns but no luck.
The following are my attempts at the markup.
<TextBox x:Name="Office" Style="{StaticResource PhoneNumber}">
<TextBox.Text>
<Binding Path="Office" Mode="TwoWay" NotifyOnValidationError="true" ValidatesOnException="true" Converter="{StaticResource PhoneNumberConverter}" />
</TextBox.Text>
</TextBox>
<TextBox x:Name="Office" Style="{StaticResource PhoneNumber}" Text="{Binding Office, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnException=true, Converter={StaticResource PhoneNumberConverter}}" />
Any ideas?
The property is not called ValidatesOnException it is called ValidatesOnExceptions note the plural.

Resources