我阅读了大部分文章,我很高兴我可以使用属性(使用 IDataErrorInfo )进行验证。那很棒。但是我浪费了几个小时仍然没有很好的解决方案,以便在 IDataErrorInfo 因为强制转换失败而未触发的情况下显示自定义消息。无论出现什么错误,它都没有意义,我想翻译它。
我应该应用自定义转换器还是自定义验证规则?
答案 0 :(得分:1)
您可以查看此博文:http://wpfglue.wordpress.com/2012/05/06/checking-property-types-automatically/
它包含有关如何设置ValidationRules的示例,以便在类型转换错误发生之前捕获它们,并将其转换为有意义的本地化错误消息。 IDataErrorInfo在这里不会帮助你,除非你真的想按照建议将所有属性包装成字符串,这是我不想做的。原因是只有在绑定对象上设置属性成功后才会查询IDataErrorInfo,如果类型不匹配则不会发生。
答案 1 :(得分:0)
我现在不知道你是如何做验证的。但请考虑使用IDataErrorInfo接口。
你可以在这里找到一个例子
http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/
答案 2 :(得分:0)
我在我的viewmodels中使用字符串属性,所以我可以使用idataerrorinfo处理每个输入。当然,我必须在调用服务时将我的字符串属性解析为正确的类型,或者将值放到我的模型中。
另一种方法是在视图中禁止输入。例如。只使用数字文本框。
或使用行为(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
}
答案 3 :(得分:0)
如果您想自定义消息,唯一的方法是实现您自己的Validation rule
。请参阅此链接以获取代码Custom Validation。