2

我阅读了大部分文章,我很高兴我可以使用属性(使用IDataErrorInfo)进行验证。那很棒。但是我浪费了几个小时,仍然没有很好的解决方案来显示自定义消息,以防 IDataErrorInfo因为投射失败而没有被触发。无论出现什么错误,它都没有任何意义,我想翻译它。 图片

我应该应用自定义转换器还是自定义验证规则?

4

4 回答 4

1

您可能想查看这篇博文:http ://wpfglue.wordpress.com/2012/05/06/checking-property-types-automatically/

它包含有关如何设置 ValidationRules 的示例,以便在类型转换错误发生之前捕获它们,并将其转换为有意义的本地化错误消息。IDataErrorInfo 在这里对您没有帮助,除非您真的想按照建议将所有属性包装成字符串,而我不想这样做。原因是绑定对象的属性设置成功后才查询IDataErrorInfo,如果类型不匹配就不会出现这种情况。

于 2012-11-15T21:22:34.170 回答
0

我在我的视图模型中使用字符串属性,所以我可以使用 idataerrorinfo 处理每个输入。当然,在调用服务或将值放入我的模型时,我必须将我的字符串属性解析为正确的类型。

另一种方法是禁止在您的视图中输入。例如。只有数字文本框。

或使用 Behaviors(Blend Sdk),例如:

<TextBox Text="{Binding MyDecimalProperty}">
        <i:Interaction.Behaviors>
            <Behaviors:TextBoxInputBehavior InputMode="DecimalInput"/>
        </i:Interaction.Behaviors>
 </TextBox>

。CS

public class TextBoxInputBehavior : Behavior<TextBox>
{
    const NumberStyles validNumberStyles = NumberStyles.AllowDecimalPoint |
                                               NumberStyles.AllowThousands |
                                               NumberStyles.AllowLeadingSign;
    public TextBoxInputBehavior()
    {
        this.InputMode = TextBoxInputMode.None;
    }

    public TextBoxInputMode InputMode { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewTextInput += AssociatedObjectPreviewTextInput;
        AssociatedObject.PreviewKeyDown += AssociatedObjectPreviewKeyDown;

        DataObject.AddPastingHandler(AssociatedObject, Pasting);

    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewTextInput -= AssociatedObjectPreviewTextInput;
        AssociatedObject.PreviewKeyDown -= AssociatedObjectPreviewKeyDown;

        DataObject.RemovePastingHandler(AssociatedObject, Pasting);
    }

    private void Pasting(object sender, DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(typeof(string)))
        {
            var pastedText = (string)e.DataObject.GetData(typeof(string));

            if (!this.IsValidInput(this.GetText(pastedText)))
            {
                System.Media.SystemSounds.Beep.Play();
                e.CancelCommand();
            }
        }
        else
        {
            System.Media.SystemSounds.Beep.Play();
            e.CancelCommand();
        }
    }

    private void AssociatedObjectPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Space)
        {
            if (!this.IsValidInput(this.GetText(" ")))
            {
                System.Media.SystemSounds.Beep.Play();
                e.Handled = true;
            }
        }
    }

    private void AssociatedObjectPreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        if (!this.IsValidInput(this.GetText(e.Text)))
        {
            System.Media.SystemSounds.Beep.Play();
            e.Handled = true;
        }
    }

    private string GetText(string input)
    {
        var txt = this.AssociatedObject;
        var realtext = txt.Text.Remove(txt.SelectionStart, txt.SelectionLength);
        var newtext = realtext.Insert(txt.CaretIndex, input);

        return newtext;
    }

    private bool IsValidInput(string input)
    {
        switch (InputMode)
        {
            case TextBoxInputMode.None:
                return true;
            case TextBoxInputMode.DigitInput:
                return CheckIsDigit(input);

            case TextBoxInputMode.DecimalInput:
                if (input.Contains("-"))
                    if (input.IndexOf("-") == 0 && input.LastIndexOf("-")==0)
                        return true;
                    else
                        return false;
                if (input.ToCharArray().Where(x => x == ',').Count() > 1)
                    return false;

                decimal d;
                return decimal.TryParse(input,validNumberStyles,CultureInfo.CurrentCulture, out d);
            default: throw new ArgumentException("Unknown TextBoxInputMode");

        }
        return true;
    }

    private bool CheckIsDigit(string wert)
    {
        return wert.ToCharArray().All(Char.IsDigit);
    }
}

public enum TextBoxInputMode
{
    None,
    DecimalInput,
    DigitInput
}
于 2012-11-15T11:39:00.277 回答
0

I don't know how you do Validation right now. But consider using the IDataErrorInfo Interface.

You can find an example here

http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/

于 2012-11-15T11:27:24.410 回答
0

如果你想自定义消息,唯一的办法就是实现你自己的Validation rule. 有关代码自定义验证,请参阅此处的链接。

于 2012-11-15T11:56:58.873 回答