简体   繁体   中英

Setting a custom type property in XAML using a static method's return type

I'm new to WPF and am trying to setup some validation for a textbox. I'm trying to determine if there's a way to set a custom type to a property through XAML by using a static method's return.

In my xaml, I currently have

<UserControl.Resources>
    <ObjectDataProvider
        ObjectType="{x:Type validators:StringValidator}" 
        MethodName="BasicValidator"
        x:Key="basicValidator"/>
</UserControl.Resources>

...

<TextBox x:Name="StrTextBox" Width="200" Height="50" >
  <TextBox.Text>
    <Binding Path="TestText" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <local:StrValidationRule ValidatorType="{StaticResource basicValidator}"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

Which throws the error on ValidatorType="{StaticResource basicValidator}"

An object of the type "System.Windows.Data.ObjectDataProvider" cannot be applied to a property that expects the type "Validator.StringValidator".

The ValidationRule is setup with a StringValidator property

public class StrValidationRule : ValidationRule
{
    public StringValidator ValidatorType { get; set; }
    ...
}

I have a class that builds specific string validators which can be accessed through static methods. For example, the static method I'm trying to call is StringValidator.BasicValidator():

public class StringValidator : IValidator<string>
{
    ...
    public static StringValidator BasicValidator()
    {
        whiteList = "abcde...";
        return new StringValidator(whiteList);
    }

    public static StringValidator BinaryValidator()
    {
        whiteList = "01";
        return new StringValidator(whiteList);
    }

    public static StringValidator NumericValidator()
    {
        whiteList = "-012345...";
        return new StringValidator(whiteList);
    }
}

And for the ValidationRule,

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
    string strValue = Convert.ToString(value);
    return ValidatorType.Validate(strValue).Match (
        Right: result => new ValidationResult(true, null),
        Left: error => new ValidationResult(false, error));
}

I have tried using x:Static, but that appears to only handle properties. I'm also unsure if I need to go about this through Binding, but that route pops up many other issues.

Is there a simple fix that I'm simply unaware of, or is there a different approach that I need to follow to solve this?

How is changing BasicValidator() into a property not a "simple fix"?

The underlying problem here is that ObjectDataProvider is specifically for use as a binding source (as the documentation explains). Normally, the way you'd use it in a situation like yours is like this:

<local:StrValidationRule ValidatorType="{Binding Source={StaticResource basicValidator}}"/>

But targets of bindings must be dependency properties, and ValidatorType isn't one, nor can it be (you have to inherit ValidationRule ). So ObjectDataProvider simply isn't usable in this exact situation.

Given the code you posted, it's not clear why you need the static method at all. You could just create a new instance in XAML, eg:

<local:StrValidationRule>
  <local:StrValidationRule.ValidatorType>
    <validators:StringValidator/>
  </local:StrValidationRule.ValidatorType>
</local:StrValidationRule>

Or just make the BasicValidator() method a static property instead.

Unfortunately, there's not enough detail in your question to provide more specific advice than that.

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