Scott Grosch

Is that possible In my custom control I have a TextBox that will either be any string value, or a numeric value. The choice depends on whether the user control's FilterType dependency property that I defined is set to string or numeric. The FilterType dependency property has a callback associated so I can do different things based on the value. Seems like a good place to do this from.

I've created a class that implements ValidationRule but I can't just directly set the TextBox.Text binding to use that rule in the XAML of the custom class as the validation isn't valid when the FilterType is Text.

So in the end I want to attach a validation rule if the FilterType is set to Numeric and not attach it if it isn't. Now I'm starting to think this could somehow be done with a trigger

Hope that makes sense.



Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

NoSuchThingAs2

I think you're right - it sounds like there's a better way to implement this scenario. How does FilterType get set Does the user get to choose "enter a string" or "enter a number" or is there some logic in your app that make the decision

From what you've already posted it seems like your ValidationRule should be smart enough to determine whether your FilterType is text or number and apply the appropriate logic, but I guess that depends on what you're doing. If you could post some sample code that would probably help.




Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

The consumer of the UserControl will do something like this:

Code Snippet

<local:UserControl1 x:Name="fsFreeFilter" Display="Free Space" Property="Free" FilterType="Size" />

<local:UserControl1 x:Name="fsProjectFilter" Display="Project" Property="IntelProject" FilterType="Button" Click="fsProjectFilter_Click" />

Then inside UserControl1.xaml.cs I do this:

Code Snippet

public static readonly DependencyProperty FilterTypeProperty =

DependencyProperty.Register("FilterType", typeof(FilterControlType), typeof(UserControl1), new UIPropertyMetadata(FilterControlType.String, FilterTypeChanged));

private static void FilterTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {

FilterControlType type = (FilterControlType) e.NewValue;

UserControl1 ctrl = d as UserControl1;

switch (type) {

case FilterControlType.String:

break;

case FilterControlType.Button:

ctrl.btn.Visibility = Visibility.Visible;

ctrl.btn.SetValue(Grid.ColumnSpanProperty, 2);

ctrl.textBox.Visibility = Visibility.Collapsed;

break;

case FilterControlType.Size:

ctrl.textBox.ClearValue(Grid.ColumnSpanProperty);

ctrl.sizeComboBox.Visibility = Visibility.Visible;

ctrl.sizeComboBox.SelectedIndex = 0;

ctrl.comboBox.Items.Clear();

ctrl.comboBox.Items.AddStrings("<", ">", "<=", ">=");

ctrl.comboBox.HorizontalContentAlignment = HorizontalAlignment.Center;

ctrl.comboBox.SelectedIndex = 0;

ctrl.comboBox.InvalidateVisual();

break;

default:

throw new InvalidOperationException("Unknown FilterControlType found.");

}

}

So when the type is FilterControlType.Size I want to attach a validation rule




Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Marlon Grech


Try something like this...

case FilterControlType.Size:

ctrl.textBox.ClearValue(Grid.ColumnSpanProperty);

ctrl.sizeComboBox.Visibility = Visibility.Visible;

ctrl.sizeComboBox.SelectedIndex = 0;

ctrl.comboBox.Items.Clear();

string[] list = new string[]{ "<", ">", "<=", ">=" };

Binding b = new Binding();

b.Source = list;

Collection<ValidationRule> col = new Collection<ValidationRule>();

col.Add(new MyValidation()); //where MyValidation is the name of your validation class

b.ValidationRules = col;

ctrl.SetBinding(ComboBox.ItemsSourceProperty, b);

ctrl.comboBox.HorizontalContentAlignment = HorizontalAlignment.Center;

ctrl.comboBox.SelectedIndex = 0;

ctrl.comboBox.InvalidateVisual();

break;







Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

b.ValidationRules is a read-only getter, it's not a setter.




Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Marlon Grech


sorry but the code that i am writing is not being tested since I am on holiday right now and my beloved laptop is at home so I do not have a Visual studio here to test the code I post (I am in an internet cafe Smile )

Anyway...

did you try to do

b.ValidationRules.Add(new MyValidationClass());

to add the validation this should work I guess....





Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

I'm still struggling with this. I tried the following:

Code Snippet

Binding b = new Binding();

b.ValidationRules.Add(new NumericValidationRule());

ctrl.textBox.SetBinding(TextBox.TextProperty, b);

as I want the validation rule to apply to the text box's input. However, when run I get an exception saying two-way binding requires a Path or XPath.





Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Marlon Grech


validations are used when you have two way data binding, now the problem is that u are not specifing the source for the binding...

what are you binding with is it still the array of strings





Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

I wasn't binding to anything. It's just a TextBox that I want to make sure has the right type of data. My CodeBehind just looks at ctrl.textBox.Text when it wants the value. This is my entire .xaml file:

Code Snippet

<UserControl x:Class="DiskUsage.UserControl1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:DiskUsage"

Name="root" Margin="5,1"

>

<UserControl.Resources>

<Style x:Key="initial" TargetType="{x:Type Control}">

<Setter Property="IsEnabled" Value="{Binding IsChecked, ElementName=checkBox}" />

<Setter Property="Visibility" Value="Collapsed" />

</Style>

<Style TargetType="{x:Type ComboBox}">

<Setter Property="IsEnabled" Value="{Binding IsChecked, ElementName=checkBox}" />

<Setter Property="SelectedIndex" Value="0" />

<Setter Property="IsEditable" Value="False" />

</Style>

</UserControl.Resources>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition SharedSizeGroup="col1" Width="Auto" />

<ColumnDefinition SharedSizeGroup="col2" Width="Auto" />

<ColumnDefinition SharedSizeGroup="col3" Width="Auto" />

<ColumnDefinition SharedSizeGroup="col4" Width="*" />

<ColumnDefinition SharedSizeGroup="col5" Width="Auto" />

</Grid.ColumnDefinitions>

<CheckBox x:Name="checkBox" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" TabIndex="1" />

<Label Grid.Column="1" Content="{Binding Display, ElementName=root}" IsEnabled="{Binding IsChecked, ElementName=checkBox}" />

<ComboBox x:Name="comboBox" Grid.Column="2" TabIndex="2">

<ComboBoxItem Content="StartsWith" />

<ComboBoxItem Content="Contains" />

<ComboBoxItem Content="EndsWith" />

<ComboBoxItem Content="Equals" />

<ComboBoxItem Content="Regex" />

</ComboBox>

<TextBox x:Name="textBox" Grid.Column="3" MinWidth="100" Grid.ColumnSpan="2" IsEnabled="{Binding IsChecked, ElementName=checkBox}" TabIndex="3" />

<ComboBox x:Name="sizeComboBox" Grid.Column="4" Style="{StaticResource initial}" TabIndex="4">

<ComboBoxItem Content="KB" />

<ComboBoxItem Content="MB" />

<ComboBoxItem Content="GB" />

<ComboBoxItem Content="TB" />

<ComboBoxItem Content="%" />

</ComboBox>

<Button x:Name="btn" Grid.Column="3" Style="{StaticResource initial}" Content="{Binding ButtonContent, ElementName=root}" />

</Grid>

</UserControl>





Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

lee d

validations will work in the context of bindings

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=2080711&SiteID=1






Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

OK, so I'm still missing something then. I added a property to the UserControl:

public string TheText { get; set; }

Then I modified the text box to include a validation rule and binding to that property (I tried as a dependency property as well):

Code Snippet

<TextBox x:Name="textBox" Grid.Column="3" MinWidth="100" Grid.ColumnSpan="2" IsEnabled="{Binding IsChecked, ElementName=checkBox}" TabIndex="3">

<TextBox.Text>

<Binding Path="TheText">

<Binding.ValidationRules>

<local:NumericValidationRule />

</< FONT>Binding.ValidationRules>

</< FONT>Binding>

</< FONT>TextBox.Text>

</< FONT>TextBox>

And I have a very simple validation rule class:

Code Snippet

public class NumericValidationRule : ValidationRule {

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) {

double val;

return new ValidationResult(double.TryParse(value.ToString(), out val), "Content must be numeric.");

}

}

The validation never happens. If I set a breakpoint inside that Validate() method, it's simply never called.




Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?


Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Marlon Grech


You need to have two way binding for the validation rule to execute

Quote from MSDN

The WPF data binding model enables you to associate ValidationRules with your Binding or MultiBinding object. You can create custom rules by subclassing the ValidationRule class and implementing the Validate method, or you can use the built-in ExceptionValidationRule, which invalidates a value if there are exceptions during source updates.

The binding engine checks each ValidationRule associated with a binding each time an input value (the binding target property value) is transferred to the binding source property. For a detailed discussion of the validation process, see the Data Validation section in the Data Binding Overview.







Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Scott Grosch

It should already be two-way as TextBox.Text defaults to two-way. However, even specifying Mode="TwoWay" explicitly on the Binding shown above makes no difference. The rule is never entered.





Re: Windows Presentation Foundation (WPF) Set a Binding.Validation rule from C#?

Marlon Grech


are you 100% sure that the source is being updated maybe there are some binding errors.....

set the NotifyOnSourceUpdated=True in the binding and hook the SourceUpdated event on your textblock....