【问题标题】:Custom error message in WPF / MVVMWPF / MVVM 中的自定义错误消息
【发布时间】:2012-11-03 23:50:45
【问题描述】:

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

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

【问题讨论】:

  • 您是否自己实现了包含错误消息的那个红框的模板?如果是这样,您的错误模板的 XAML 是什么样的?
  • 因为你喜欢它还是因为它有帮助?这与 silverlight error template question 这里的问题类似。我只是对它做了一些修改:) 我在那里有评论stackoverflow.com/a/7437765/294022
  • 也许我误解了你的问题。是否要替换文本“无法转换值'gg'”?或者是其他东西。我询问了错误模板,因为如果您想替换文本,那么您就可以这样做...
  • 是的,我想替换这个自动生成的文本
  • 好吧,文本是自动生成的,但大概您仍然使用 {Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[ 0].错误内容} ?我将通过以下方式更改该绑定:(a)使用您可以自己控制的视图模型中的不同字符串属性,或者(b)使用绑定中的值转换器将系统的字符串转换为您自己的字符串

标签: wpf mvvm


【解决方案1】:

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

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

【讨论】:

  • 我看起来很有希望。字符串属性是维护的噩梦,我猜字符串格式也消失了。
【解决方案2】:

我不知道您现在如何进行验证。但请考虑使用 IDataErrorInfo 接口。

你可以在这里找到一个例子

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

【讨论】:

  • 正如我所说,我使用 IDataErrorInfo 但如果您将文本放在绑定到小数/整数等的文本框中,您将无法处理和自定义此错误..
  • 抱歉,我错过了那句话。我认为 ErrorInfo 接口只是为了提供有关错误的通知,而不是处理错误本身。您应该在输入控件中进行这种验证
【解决方案3】:

如果你想自定义消息,唯一的办法就是实现你自己的Validation rule。请参考此链接获取代码Custom Validation

【讨论】:

    【解决方案4】:

    我在我的视图模型中使用字符串属性,所以我可以使用 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
    }
    

    【讨论】:

    • 纯数字文本框我相信当你想处理金钱时它不是微不足道的。另一处房产将是我最后的选择
    • 我根本不使用纯数字文本框。我使用的是行为。
    猜你喜欢
    • 2018-08-12
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多