我正在尝试在实现新架构的同时,对我们现有产品的一组相当复杂的技术进行一些验证。其中大部分进展顺利,但是我仍然需要对现有产品使用 WinForms,因此需要使用 ErrorProvider
类来显示验证错误。(新产品也将能够通过WPF/MVC使用新体系结构,但是目前我没有时间或资源从头开始完全重写以消除WinForms,因此混合了技术(
新架构的基本布局如下:
Database -> Model (via NHibernate) -> ViewModel -> Form (using BindingSource)
所以我的问题是,我如何利用失败的DataAnnotation
检查中的ValidationResult
对表单上ErrorProvider
上的模型属性?
我已经设法将ValidationResults
列表设置为表单,但将它们设置为特定控件是在暗示我没有为每个控件编写代码,我更愿意通过 BindingSource
创建一种通用的方式来执行此操作,可能是在基本窗体中。
我知道如果DataAnnotations
在 ViewModel 上,我可以更轻松地执行此操作,但是如果我这样做,那么如果对模型/数据库表进行更改,我必须使所有这些表保持最新状态,这将需要大量重复代码。
我知道这个问题有点模糊,但考虑到这跨越了大部分架构的事实,如果不编写大量几乎不相关的代码,我就看不到更好的方法来解释它。如果您需要更多信息,请询问,我会提供。
非常感谢。
这是否有帮助,但看看是否将您的btn_Save更改为这样,然后添加 GetControlBoundToMember 方法,我猜您的 btnSave 方法看起来类似于下面的方法。您还需要将 ErrorProvider 控件添加到窗体中并调用它 err1,并将可能位于分组框中的任何控件移出 groupbo 并将它们放在窗体上,除非您创建一个递归方法来搜索具有控件集合的控件。
private void btnSave_Click(object sender, EventArgs e)
{
if (_entity != null)
{
try
{
_service.Save(_entity.UpdateEntity());
}
catch (InvalidOperationException ex)
{
//do something here to display errors
listBox1.Items.Clear();
foreach (var r in _entity.Errors)
{
listBox1.Items.Add(r.ErrorMessage);
foreach (var c in GetControlBoundToMember(r.MemberNames.ToList()))
{
err1.SetError(c, r.ErrorMessage);
}
}
}
}
}
private IList<Control> GetControlBoundToMember(IList<string> memberNames)
{
List<Control> controls = new List<Control>();
foreach (Control control in this.Controls)
{
foreach (var mn in memberNames)
{
foreach (Binding binding in control.DataBindings)
{
if (binding.BindingMemberInfo.BindingField == mn) controls.Add(control);
}
}
}
return controls;
}
血型