简体   繁体   中英

How do I pass additional data into a ValidationRule?

I have a validation rule created as such:

public class TagFitsConstraintRule : ValidationRule
{
    public TagDependencyObject SelectedTag { get; set; }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        Tag tag = SelectedTag.Tag;

        if (tag != null)
        {
            if (tag.TagConstraintPattern == null)
            {
                return ValidationResult.ValidResult;
            }
            else
            {
                // Perform additional validation for the tag
            }
        }
        else
        {
            return new ValidationResult(false, "No tag selected.");
        }
    }
}

The Dependency object is defined as:

public class TagDependencyObject : DependencyObject
{
    public static readonly DependencyProperty TagProperty = DependencyProperty.Register("Tag", typeof(Tag), typeof(TagDependencyObject), new UIPropertyMetadata(null));

    public Tag Tag
    {
        get { return (Tag)GetValue(TagProperty); }
        set { SetValue(TagProperty, value); }
    }
}

And I'm using it in XAML as:

<Window
...>
<Window.Resources>
    <d:TagDependencyObject x:Key="TagDependencyObject" Tag="{Binding CurrentlySelectedTag}"/>
</Window.Resources>
...
<TextBox ... >
    <TextBox.Text>
        <Binding Path="CurrentlySelectedTag" Converter="{StaticResource TagDataConverter}" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <c:TagFitsConstraintRule ValidatesOnTargetUpdated="True" SelectedTag="{StaticResource TagDependencyObject}"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
...

And for whatever reason I can't seem to wrap my brain around, the Tag property on the TagDependencyObject does not budge from being set to null. I've tried manipulating the binding Mode, the UpdateSourceTrigger, nothing seems to work. I know for a fact that the property on my ViewModel is populated as other components on the window are acing appropriately. I have also verified that the ViewModel property is getting set before the ValidationRule is ran. What am I doing wrong?

I intentionally worded the question the way I did because, perhaps, there is a much better way to be doing what I want to do that I'm not aware of, so i'm open to alternatives. My end goal is to provide validation on the TextBox listed in the XAML above, but I need more than just the text in the TextBox to do the actual validation (just a couple of properties off the Tag class).

I'm basically following what's described on the following sites.

Site 1 Site 2

I was able to do this using a converter. I used a IMultiValueConverter so I could get each of the properties I needed passed to the converter.

Converter:

public class MyCoolConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Logic
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Binding:

<TextBox Text="{Binding CurrentlySelectedTag.TagData, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.Style>
        <MultiBinding Converter="{StaticResource TagDataValidationStyleSelector}" UpdateSourceTrigger="PropertyChanged">
            <Binding Path="CurrentlySelectedTag"/>
            <Binding Path="CurrentlySelectedTag.TagData" UpdateSourceTrigger="PropertyChanged"/>
        </MultiBinding>
    </TextBox.Style>
</TextBox>

And the validation part that doesn't seem to be explained very well in the documentation... You'll get the similar red-box-outline visual error on your input by throwing exceptions from your converter by setting ValidateOnDataErrors=true on your validation template, which appears to be the default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM