提问人:aca 提问时间:2/24/2023 最后编辑:EldHaspaca 更新时间:2/25/2023 访问量:153
如何在ViewModel中获取ValidationResult方法的结果?(对/错)
How to get the result of a ValidationResult method, inside ViewModel? (True / False)
问:
我有一个这样的(部分)文件XAML
<TextBox.Text>
<Binding Path="MyProperty"
UpdateSourceTrigger="PropertyChanged"
TargetNullValue="">
<Binding.ValidationRules>
<validation:IntRangeRule Min="-999"
Max="999" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
像这样的班级IntRangeRule
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value != null)
{
var stringToConvert = value as string;
if (!string.IsNullOrEmpty(stringToConvert))
{
Int32 number;
bool result = Int32.TryParse(stringToConvert, NumberStyles.Integer, cultureInfo, out number);
if (!result)
{
var localizer = ServiceLocator.Current.GetInstance<IResourceLocalizer>();
return new ValidationResult(false, string.Format(localizer["IntValidationError"], stringToConvert, Min, Max));
}
if ((number < Min) || (number > Max))
{
var localizer = ServiceLocator.Current.GetInstance<IResourceLocalizer>();
return new ValidationResult(false, string.Format(localizer["IntRangeValidationError"], Min, Max));
}
}
}
return new ValidationResult(true, 0);
}
由于我意识到当具有第一个参数时,它不会更改属性。ValidationResult
false
MyProperty
因此,我的目标是以某种方式在 ViewModel 中确认是真是假,这样我就可以在我的语句中使用这些信息。到目前为止,我找不到如何做到这一点。ValidationResult
if
答:
-1赞
Andy
2/24/2023
#1
像这样的验证器在存在 validation.error 时会引发一个路由事件,而在修复时会引发另一个路由事件。正如您所注意到的,没有将数据从视图传输到视图模型。
有一个路由事件引发,您可以在父级中处理该事件。比如说,在网格中或在用户控制级别。
显然,您需要一种方法来告诉视图模型是否存在错误。
在处理事件的父级中,可以设置一个依赖项属性,该属性绑定到视图模型中的属性。
这是一些旨在为您提供想法的旧代码。它可能不会剪切和粘贴,因为它很旧。
在父网格或用户控件中,或者可以通过将此类内容放在 contentcontrol 的模板中来使其更易于重用。然后将 ui 放在该控件中。
下面使用命令。
<Grid>
<i:Interaction.Triggers>
<UIlib:RoutedEventTrigger RoutedEvent="{x:Static Validation.ErrorEvent}">
<e2c:EventToCommand
Command="{Binding ConversionErrorCommand, Mode=OneWay}"
EventArgsConverter="{StaticResource BindingErrorEventArgsConverter}"
PassEventArgsToCommand="True" />
命令的事件来自 mvvm light。我提到不是剪切和粘贴解决方案。
转炉
public class BindingErrorEventArgsConverter : IEventArgsConverter
{
public object Convert(object value, object parameter)
{
ValidationErrorEventArgs e = (ValidationErrorEventArgs)value;
PropertyError err = new PropertyError();
err.PropertyName = ((System.Windows.Data.BindingExpression)(e.Error.BindingInError)).ResolvedSourcePropertyName;
err.Error = e.Error.ErrorContent.ToString();
// Validation.ErrorEvent fires both when an error is added AND removed
if (e.Action == ValidationErrorEventAction.Added)
{
err.Added = true;
}
else
{
err.Added = false;
}
return err;
}
}
请注意在添加错误和删除错误时如何命中它。
路由事件触发器。
// This is necessary in order to grab the bubbling routed source changed and conversion errors
public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
RoutedEvent routedEvent;
public RoutedEvent RoutedEvent
{
get
{
return routedEvent;
}
set
{
routedEvent = value;
}
}
public RoutedEventTrigger()
{
}
protected override void OnAttached()
{
Behavior behavior = base.AssociatedObject as Behavior;
FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement;
if (behavior != null)
{
associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
}
if (associatedElement == null)
{
throw new ArgumentException("This only works with framework elements");
}
if (RoutedEvent != null)
{
associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
}
}
void OnRoutedEvent(object sender, RoutedEventArgs args)
{
base.OnEvent(args);
args.Handled = true;
}
protected override string GetEventName()
{
return RoutedEvent.Name;
}
}
评论