I have a textbox that has validation on it, in the validation checks to see if its isNullOrEmpty. The validation works but what I am having difficulty is if the user never selects the textbox and clicks save, I want the validation to run again.
I was able to accomplish this in the XAML.cs file using:
Validation.MarkInvalid(cb.GetBindingExpression(dp), validationError);
Now with MVVM I'm confused how I am able to accomplish this from the viewmodel.
Textbox in question:
<TextBox>
<TextBox.Text>
<Binding Path="LastName">
<Binding.ValidationRules>
<validationRules:IsNullOrEmptyValidationRule/>
</Binding.ValidationRules>
<Binding.UpdateSourceTrigger>PropertyChanged</Binding.UpdateSourceTrigger>
<Binding.Mode>TwoWay</Binding.Mode>
</Binding>
</TextBox.Text>
</TextBox>
Any ideas?
Related
I'm rather new to WPF and XAML, and I'm attempting to create a custom class that extends TextBox, so that I can add some properties for easier validation setup. The validation works fine. The problem is, when I swap out the TextBox in the XAML, the new TextBox updates the border to display an error, but the tool-tip does not show up as expected (see below).
In the picture below, the top 's error tool tip displays correctly, but the 's tool-tip doesn't.
Here's the XAML...
<TextBox x:Name="StrTextBox3" Width="200" Height="50">
<TextBox.Text>
<Binding Path="BinaryIntText" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validationRules:StrValidationRule ValidatorType="{x:Static validators:StringValidator.BinaryOnly_Validator}"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<validationRules:ValidatedTextBox x:Name="VText" Width="200" Height="50">
<TextBox.Text>
<Binding Path="BinaryIntText2" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validationRules:StrValidationRule ValidatorType="{x:Static validators:StringValidator.BinaryOnly_Validator}"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</validationRules:ValidatedTextBox>
And here's the extending class...
class ValidatedTextBox : TextBox
{
public ValidatedTextBox()
{
//
}
}
And the ValidationRule for good measure...
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return ValidatorType.Validate(Convert.ToString(value)).Match (
Right: result => new ValidationResult(true, null),
Left: error => new ValidationResult(false, error));
}
How do I go about enabling this functionality? Have I not initialized a particular field or two? Am I missing calls to something else? Am I plagued by styles, or some other straight-forward thing that is a quicker fix than doing this write up?
Thank you
Turns out I'm dense; by simply extending the TextBox, the default Style for TextBoxes was not applied, and setting the new Style to an existing TextBox's Style, or just setting in at all, fixed the issue.
I have a WPF UserControl which allows the editing of an data object (VariableDataGroup). When I use the following syntax the binding works and my user control displays correctly:
<vdi:VariableDataPageView DataContext="{Binding VariableData}" Grid.Row="4" Grid.Column="1" >
Where VariableData is a property on the parent screen's ViewModel.
However, when I try and use the "<Binding>" syntax then my user control doesn't display the data.
<vdi:VariableDataPageView Grid.Row="4" Grid.Column="1" >
<Binding Path="VariableData" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<!--<Binding.ValidationRules>
<validation:VDIComittedValidationRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>-->
</Binding>
</vdi:VariableDataPageView>
The reason I want to switch to using the syntax is to use a custom validation rule to fit in with the exiting code.
First Question: What would be the equivalent syntax to 'DataContext="{Binding VariableData}"' ?
Second Question: Is there a recommended way of performing validation in a UserControl and integrating that with the validation on the parent view? The way I think it should work is that the UserControl performs all its own validation and just passes a validated yes/no result to the parent page but the whole WPF model of programming is new to me.
Thanks,
Canice.
The equivalent syntax to DataContext="{Binding VariableData}"
<vdi:VariableDataPageView Grid.Row="4" Grid.Column="1" >
<vdi:VariableDataPageView.DataContext>
<Binding Path="VariableData" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<!--<Binding.ValidationRules>
<validation:VDIComittedValidationRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>-->
</Binding>
</vdi:VariableDataPageView.DataContext>
</vdi:VariableDataPageView>
In Prism application I want to using validation.And I have implement the INotifyDataError interface in my ViewModel ,but I found that the validate solution don't be fired when the control is loaded first time.
Then I found the same Question like 'wpf Validation Binding not fired on First Load'
I Found a solution to solve the problem WPF don't fired the validation when first load the datacontext is that:
<TextBox Grid.ColumnSpan="2" Grid.Row="1" x:Name="textBoxFolder" Margin="2,4">
<TextBox.Text>
<Binding Path="this.MovieFolder" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<!-- Validation rule set to run when binding target is updated. -->
<Rules:MandatoryInputRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
as you see,ValidatesOnTargetUpdated="True" is the key point ,this property will make WPF fired the validation when the datacontext load first time.
But I think that's a ugly solution. I need to add a Binding.ValidationRules for every control I want to validate.
Is there a good way to solve the problem.
OK I've solved it: You force the validation when the element got bound with a simple property - ValidatesOnTargetUpdated:
<rules:MyValidationRule ValidatesOnTargetUpdated="True" ValidationType="notnull"/>
I have a TextBox with OneWay Mode, so validation does not happen automatically.
<TextBox.Text>
<Binding Path="SelectedValue.Customername"
ElementName="customerListBox"
Mode="OneWay"
>
<Binding.ValidationRules>
<validators:NameValidator ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
I have a button :
<Button Content="Save" Command="{Binding SaveCommand}"/>
Now on ViewModel , I want to validate the Text Input before doing anything else:
SaveCommand = new RelayCommand(
param=>
{
//If validation is true
//Then Execute Res
}
);
Ditch the UI validation rules and have your VM implement IDataErrorInfo and INotifyDataErrorInfo.
Think about it--your save command should not execute unless the data in your VM is valid. That means the validation logic should be in your VM, and not in your UI.
Implementing these interfaces makes it trivial to check whether or not you execute/can execute and fire appropriate events when CanExecute has changed.
A ComboBox.SelectedItemProperty is bound TowWay to a DependencyProperty in
The Control.
In the ControlTemplate :
<ComboBox IsEditable="True">
<ComboBox.SelectedItem>
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="SomeDP" Mode="TwoWay" NotifyOnValidationError="True">
<Binding.ValidationRules>
<vld:DeleteAfterInitValidationRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
When the ValidationRule returns false
return ValidationResult(false,msg);
The Dependency Property bound to selected item is not updated.
Is there a way to force the binding to update the source ?
*Please if any one is going to raise a discussion here about
BindingExpression.UpdateSource() , please supply a working example, and not just blurt it out because it sounds like the solution ,
i do not intend to use Explicit mode on my Binding.
Further more i can easily code my way around this but a good .net programmer should thrive to write less code and use the built in mechanisms supplied by the .net framework ,
And that is the soul purpose of this question , is there a built in way of updating the source while
notifying of a DataError ?