我正在寻找为用户控件中包含的所有控件设置验证组的最佳方法。控件中的大多数控件都是在加载控件时动态创建的。它有相当多的输入字段和验证器。
我希望通过使用某种函数来设置所有控件和验证器的验证,从而节省时间,这些函数可以遍历所有内容并进行设置。
但是,似乎没有一致的接口来包含具有该属性的所有不同控件的验证组。
我是否应该使用反射来检查验证组,我知道我可以这样做,但有没有更好的方法?
顺便说一下,我们正在使用C#。
任何帮助都将不胜感激。谢谢!
编辑:我在下面为任何想要代码的人写下了答案。
发布于 2011-01-18 23:22:37
我只想把这个标记为已回答。
下面是我用来设置验证组的代码。我决定使用反射,因为我可以检查那些我知道有ValidationGroup的类型,并强制转换和设置,但有很多类型需要检查,它可能会遗漏未来可能添加的新控件。如果ValidationGroup是某种必须实现的接口的一部分,那就太好了。
/// <summary>
/// this is an extension method to iterate though all controls in a control collection
/// put this in some static library somewhere
/// </summary>
/// <param name="controls"></param>
/// <returns></returns>
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
/// <summary>
/// this function uses reflection to check if the validation group exists, and then set it to the
/// specified string
/// </summary>
/// <param name="ValidationGroup"></param>
private void SetValidationGroup(string ValidationGroup)
{
//set the validation group for all controls
if (ValidationGroup.IsNotNullOrEmpty())
{
foreach (Control c in Controls.All())
{
var Properties = c.GetType().GetProperties();
var vg = Properties.Where(p => p.Name == "ValidationGroup").SingleOrDefault();
if (vg != null)
{
vg.SetValue(c, ValidationGroup, null);
}
}
}
}发布于 2010-11-23 22:41:28
我最近遇到了一个非常类似的问题-我使用的解决方案是创建两个扩展方法,它们可以循环遍历控件的所有子控件/后代控件,找到特定类型的控件,然后调用它们的子例程(例如,此子例程可以设置控件的任何属性)。下面是VB.Net中的代码(很抱歉,这是我们在工作中使用的代码,我相信代码翻译器应该能够为您解决这个问题)。
Public Module ControlExtensionMethods
''' <summary>
''' Gets all validation controls used by a control.
''' </summary>
''' <param name="onlyGetVisible">If true, will only fetch validation controls that currently apply (i.e. that are visible). The default value is true.</param>
''' <returns></returns>
''' <remarks></remarks>
<Extension()>
Public Function GetAllValidationControls(ByVal target As Control, Optional ByVal onlyGetVisible As Boolean = True) As ReadOnlyCollection(Of BaseValidator)
Dim validators As New List(Of BaseValidator)
GetControlsOfType(Of BaseValidator)(target, Function(x) Not onlyGetVisible OrElse x.Visible = onlyGetVisible, validators)
Return validators.AsReadOnly()
End Function
''' <summary>
''' Gets if the control is in a valid state (if all child/descendent validation controls return valid)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
<Extension()>
Public Function IsValid(ByVal target As Control) As Boolean
Return target.GetAllValidationControls().All(Function(x)
x.Validate()
Return x.IsValid
End Function)
End Function
''' <summary>
''' Iteratively fetches all controls of a specified type/base type from a control and its descendents.
''' </summary>
''' <param name="fromControl"></param>
''' <param name="predicate">If provided, will only return controls that match the provided predicate</param>
''' <remarks></remarks>
<Extension()>
Public Function GetControlsOfType(Of T As Control)(ByVal fromControl As Control, Optional ByVal predicate As Predicate(Of T) = Nothing) As IList(Of T)
Dim results As New List(Of T)
GetControlsOfType(fromControl, predicate, results)
Return results
End Function
Private Sub GetControlsOfType(Of T As Control)(ByVal fromControl As Control, ByVal predicate As Predicate(Of T), ByVal results As IList(Of T))
'create default predicate that always returns true if none is provided
Dim cntrl As Control
If predicate Is Nothing Then predicate = Function(x) True
If fromControl.HasControls Then
For Each cntrl In fromControl.Controls
GetControlsOfType(Of T)(cntrl, predicate, results)
Next
End If
If TypeOf fromControl Is T AndAlso predicate(fromControl) Then
results.Add(fromControl)
End If
End Sub
End Module使用此代码禁用所有验证器的示例:
Array.ForEach(myUserControl.GetAllValidationControls().ToArray(), sub(x) x.Enabled = False)发布于 2013-12-19 23:10:48
我刚才正在与这个问题正面交锋,并提出了一个不涉及到鸭子打字的替代解决方案:
string newGroup = "foo";
IEnumerable<BaseValidator> validators = this.Controls.OfType<BaseValidator>();
IEnumerable<Button> buttons = this.Controls.OfType<Button>();
foreach (var validator in validators)
validator.ValidationGroup = newGroup;
foreach (var button in buttons)
button.ValidationGroup = newGroup;这也可能是另一种选择:
foreach (var c in this.Controls)
{
if (c is BaseValidator)
(c as BaseValidator).ValidationGroup = newGroup;
else if (c is Button)
(c as Button).ValidationGroup = newGroup;
}https://stackoverflow.com/questions/4257023
复制相似问题