gpt4 book ai didi

c# - Caliburn.Micro 实现 INotifyDataErrorInfo

转载 作者:太空宇宙 更新时间:2023-11-03 13:22:07 28 4
gpt4 key购买 nike

我正试图找到一个优雅的解决方案来使用 Caliburn.Micro MVVM 框架实现 INotifiyDataErrorInfo

我想限制将在每个需要实现验证的虚拟机中重复的代码量。我首先编写了一个继承 Screen 并实现 INotifiyDataErrorInfo 的类。它工作正常并且一切正常,直到我需要在不是 Screen 而是 Conductor 的 VM 上进行验证。

当然,我可以创建一个继承 Conductor 并实现 INotifyDataErrorInfo 的类,但这很烦人,因为我基本上必须制作我自己的所有“基础”版本Caliburn.Micro 的类。

我的一个解决方案是保留 Screen 基类并创建一个 IValidator 接口(interface),我将其注入(inject)到我的 VM 中,如下所示:

public interface IValidator<T> where T : INotifyDataErrorInfo
{
void Validates(T instance);

IEnumerable GetErrors(string propertyName);
bool HasErrors { get; }

void Validate();
void ValidateProperty<TValue>(TValue value, string propertyName = null);
void ValidateProperty<TValue, TProperty>(TValue value, Expression<Func<TProperty>> property);
}

然后它将以这种方式在 VM 中使用。

public class CreateCarViewModel : Conductor<CreateCarViewModel>.Collection.OneActive, INotifyDataErrorInfo
{
private readonly IValidator<CreateCarViewModel> validator;

public CreateExperimentViewModel(IValidator<CreateCarViewModel> validator)
{
this.DisplayName = "Select a car";

this.validator = validator;
this.validator.Validates(this);
}

[Required]
public string CarName
{
get
{
return this.carName;
}
set
{
if (this.carName != value)
{
this.carName = value;

this.validator.ValidateProperty(value, () => this.CarName);
this.NotifyOfPropertyChange(() => CarName);
}
}
}

public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

public System.Collections.IEnumerable GetErrors(string propertyName)
{
return this.validator.GetErrors(propertyName);
}

public bool HasErrors
{
get { return this.validator.HasErrors; }
}

...

}

这非常有效,因为在 VM 中实现 INotifyDataErrorInfo 非常简单,但我遇到的问题是触发 ErrorChanged 事件。它必须由 IValidator 的实现触发,因为他知道错误何时发生变化,当然他不能直接触发。

我的一个想法是在 IValidator 中创建一个事件并在 VM 中订阅它,以便它可以触发自己的事件,但我发现它白白写了很多代码.

有没有人有更好的主意?

谢谢

最佳答案

我为 CM 编写了一个小插件来启用流畅的构建器式验证。也许它会对你有所帮助。欢迎使用:https://github.com/AIexandr/Caliburn.Micro.Validation使用示例:

public class PaymentEditorViewModel() : ValidatingScreen
{
public PaymentEditorViewModel()
{
AddValidationRule(() => PaymentSum).Condition(() => PaymentSum <= 0).Message("Please enter payment sum");
}

#region PaymentSum property
decimal _PaymentSum;
public decimal PaymentSum
{
get
{
return _PaymentSum;
}
set
{
_PaymentSum = value;
NotifyOfPropertyChange(() => PaymentSum);
}
}
#endregion
}

关于c# - Caliburn.Micro 实现 INotifyDataErrorInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23777395/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com