2010-11-23 9 views
2

私は、ユーザーコントロールに含まれるすべてのコントロールの検証グループを設定する最適な方法を探しています。コントロール内のほとんどのコントロールは、コントロールがロードされると動的に作成されます。かなりの数の入力フィールドとバリデーターがあります。設定方法ユーザーコントロールのすべてのコントロールの検証?

私は、すべてのコントロールとバリデータの検証を、すべてをループして設定できる何らかの関数で設定することで、時間を節約したいと考えています。

プロパティを持つすべての異なるコントロールの検証グループを含む一貫したインターフェイスはないようですが、

検証グループを確認するためにリフレクションを使用する必要がありますが、これを行うことができますが、より良い方法はありますか?

私たちは途中でC#を使用しています。

ご協力いただければ幸いです。ありがとう!

編集:私はコードを望む人のために答えを下に置きます。

答えて

1

ただ、これが答えマークしたかったです。

ここでは、検証グループの設定に使用したコードを示します。私はリフレクションを使用することにしました。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); 
      } 

     } 

    } 
} 
1

私は最近、非常によく似た問題を抱えていました。私が使用した解決法は、コントロールの子コントロールまたは子コントロールのすべてをループし、特定のタイプのコントロールを探し出し、それらのサブルーチンを呼び出す拡張メソッドをいくつか作成することでした(このサブルーチンは、例えば、コントロールの任意のプロパティを設定することができます)。コードは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) 
+0

それは良いですが、私は必要なものではありません。コードではバリデータのリストしか返されないと思いますが、私が探しているのは、テキストボックス、ボタン、検証サマリーなどのValidationGroupプロパティを持つものです。 –

+0

GetControlsOfType()関数で述語を指定することができますので、これを行います:userControl.GetControlsOfType(Of Control)(sub(x)x.ValidationGroup = "myValidationGroup") – WiseGuyEh

+0

私は、ValidationGroupプロパティを持つ可能性のあるすべてのコントロールタイプに対してこの関数を呼び出さなければならないでしょう。 –

0

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; 
} 
関連する問題