WPF TextBox control filter + validation - wpf

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.

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;

WPF MVVM How read property value, binded to another element, in viewmodel

I'm trying to do a simple thing, I've searching around the web but I've not found a solution. I use ColorPicker from Wpf Toolkit library, the property SelectedColor is binded to an element Label on Foreground Property.
It works correctly, when I change color from color picker the label changes its color, but I can't find a way to get the selected color in my viewmodel.
Normally I used to bind my property to viewmodel and manage it on onPropertyChanged event, but how can I do in this situation?
XAML
<Label Name="LabelMeasureValue1" Content="{Binding TrendingMeasure1Value}" Style="{StaticResource LabelStyleBold}" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="2"/>
<wpfTool:ColorPicker Name="ColorPick1" DisplayColorAndName="True" ShowStandardColors="False" AvailableColors="{Binding ColorItems}" SelectedColor="{Binding ElementName=LabelMeasureValue1, Path=Foreground, Converter={StaticResource brushColorConv}}" Tag="{Binding Path=SelectedItem, ElementName=ComboBoxMeasure1}" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Height="30">
<wpfTool:ColorPicker.IsEnabled>
<MultiBinding Converter="{StaticResource enblTrendConv}">
<Binding Path="Device.EsitoUltimaLettura" />
<Binding Path="IsGraphRunning" Converter="{StaticResource invBoolValueConv}"/>
</MultiBinding>
</wpfTool:ColorPicker.IsEnabled>
</wpfTool:ColorPicker>

Binding Row to Validation Rule WPF

I want to bind TextBox's Tag (which is inside a DataGrid), to validation rule's CurrentLegStrategy property (which is a DependencyProperty). Although I've done something similar with Deal dependency property using a global tunnel object, however not able to figure out, what would be the tunnel for CurrentLegStrategy (ideally should be coming from the bound data to DataRow or to the bound data to TextBox's tag)?
<DataTemplate x:Key="PremiumProp">
<TextBlock Style="{StaticResource TextBlockLeft}" Tag="{Binding Strategy}" x:Name="txtPremiumProp">
<TextBlock.Text>
<Binding Path="AbsolutePremium" StringFormat="{}{0:#,##0.00####}" Converter="{StaticResource _DoubleConvertor}">
<Binding.ValidationRules>
<Control:MBSStrategyBasedDoubleValidation ValidatesOnTargetUpdated="True" ValidationTag="premabs"
ErrorMessage="Please enter a valid positive (+) premium (also check the reference which is required for auto calculation)!">
<Control:MBSStrategyBasedDoubleValidation.Deal>
<Control:DealObject Deal="{Binding Tag, Source={StaticResource TradeTunnel}}" CurrentLegStrategy="{Binding Path=Tag, ElementName=txtPremiumProp}"/>
</Control:MBSStrategyBasedDoubleValidation.Deal>
</Control:MBSStrategyBasedDoubleValidation>
</Binding.ValidationRules>
</Binding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
Then I also tried,
<TextBlock.Resources>
<ResourceDictionary>
<FrameworkElement x:Name="strategySource" Tag="{Binding Tag, Source={x:Reference txtPremiumProp}}"/>
</ResourceDictionary>
</TextBlock.Resources>
With the following:
CurrentLegStrategy="{Binding Path=Tag, Source={StaticResource strategySource}}"
Cannot find resource named 'strategySource'. Resource names are case sensitive.

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 ValidationRules disables PropertyChanged

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>

Resources