【问题标题】:Setting a custom type property in XAML using a static method's return type使用静态方法的返回类型在 XAML 中设置自定义类型属性
【发布时间】:2020-11-11 02:52:03
【问题描述】:

我是 WPF 新手,正在尝试为文本框设置一些验证。我正在尝试确定是否可以通过使用静态方法的返回通过 XAML 将自定义类型设置为属性。

在我的 xaml 中,我目前有

<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>

这会在 ValidatorType="{StaticResource basicValidator}" 上引发错误

“System.Windows.Data.ObjectDataProvider”类型的对象不能应用于需要“Validator.StringValidator”类型的属性。

ValidationRule 使用 StringValidator 属性设置

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

我有一个类可以构建可以通过静态方法访问的特定字符串验证器。例如,我试图调用的静态方法是 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);
    }
}

对于 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));
}

我尝试过使用 x:Static,但这似乎只处理属性。我也不确定我是否需要通过 Binding 来解决这个问题,但这条路线会弹出许多其他问题。

是否有一个我根本不知道的简单修复方法,或者我需要采用不同的方法来解决这个问题?

【问题讨论】:

    标签: c# wpf xaml data-binding wpf-controls


    【解决方案1】:

    如何将BasicValidator() 更改为属性而不是“简单修复”?

    这里的根本问题是ObjectDataProvider 专门用作绑定源(正如the documentation 解释的那样)。通常,您在像您这样的情况下使用它的方式是这样的:

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

    但绑定的目标必须是依赖属性,ValidatorType 不是,也不能是(你必须继承ValidationRule)。所以ObjectDataProvider 在这种情况下根本不可用。

    鉴于您发布的代码,您根本不清楚为什么需要静态方法。您可以在 XAML 中创建一个新实例,例如:

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

    或者只是将BasicValidator() 方法设为静态属性。

    很遗憾,您的问题中没有足够的细节来提供比这更具体的建议。

    【讨论】:

    • 嘿,彼得,抱歉解释不佳。我使用 StringValidator 类的静态方法返回专门构建的 StringValidator 版本,我希望能够将其放入 ValidationRule 的 ValidatorType 属性中。例如,我有一个只接受像“abc”这样的基本字符,称为“BasicValidator()”,还有一个只针对数字字符进行验证,称为“NumericValidator()”。我已经对帖子进行了一些编辑,希望这有助于更好地解释我所追求的。
    • “我有一个只接受像“abc”这样的基本字符,称为“BasicValidator()”,还有一个只针对数字字符进行验证”——好的,但是为什么不只是使每个不同的静态属性?无论如何,像这样的东西通常会从单例方法中受益,所以在我看来,这很自然。
    • 谢谢你,我把它复杂化了。我最初不想将静态方法更改为属性,因为它最初不是我编写的,但这很好地解决了这个问题。
    猜你喜欢
    • 2021-10-19
    • 2021-12-27
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2020-04-27
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多