2010-11-23 2 views
2

Ich bin auf der Suche nach der besten Möglichkeit zum Festlegen der Validierungsgruppe für alle Steuerelemente in einem Benutzersteuerelement enthalten. Die meisten Steuerelemente in dem Steuerelement werden dynamisch erstellt, wenn das Steuerelement geladen wird. Es hat einige Eingabefelder und Validatoren.Wie wird die Überprüfung für alle Steuerelemente in einem Benutzersteuerelement festgelegt?

Ich möchte Zeit sparen, indem ich die Validierung für alle Steuerelemente und Validatoren mit einer Art von Funktion, die einfach alles durchlaufen und setzen könnte.

Es scheint jedoch, dass es keine konsistente Schnittstelle gibt, die eine Validierungsgruppe für alle verschiedenen Steuerelemente mit der Eigenschaft enthält.

Sollte ich Reflexion verwenden, um nach Validierungsgruppe zu suchen, weiß ich, dass ich das tun kann, aber gibt es einen besseren Weg?

Wir verwenden C# übrigens.

Jede Hilfe wäre willkommen. Vielen Dank!

EDIT: Ich habe die Antwort unten für jeden, der den Code will.

Antwort

1

Ich wollte nur diese beantwortet markieren.

Hier ist der Code, den ich verwendet habe, um die Validierungsgruppe zu setzen. Ich entschied mich dafür, Reflektionen zu verwenden, da ich Typen überprüfen konnte, für die ich ValidationGroup kenne, und zwar cast und set, aber es gibt eine Menge zu überprüfender Typen, und es könnten neue Steuerelemente fehlen, die in der Zukunft hinzugefügt werden könnten. Wäre schön gewesen, wenn die ValidationGroup Teil einer Art Schnittstelle gewesen wäre, die die Dinge implementieren mussten.

/// <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

Ich hatte vor kurzem ein sehr ähnliches Problem - die Lösung, die ich verwendet habe, war ein paar Extension-Methoden, die Schleife über alle untergeordneten/untergeordneten Steuerelemente eines Steuerelements, finden Sie einen bestimmten Typ und dann ein Unterprogramm auf ihnen aufrufen (Diese Subroutine könnte beispielsweise alle Eigenschaften eines Steuerelements festlegen). Der Code ist unten in VB.Net (sorry, das ist, was wir bei der Arbeit verwenden, ich bin sicher, dass ein Code-Übersetzer in der Lage sein sollte, dies für Sie zu sortieren).

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 

Ein Beispiel für diesen Code mit allen Validatoren deaktivieren:

Array.ForEach(myUserControl.GetAllValidationControls().ToArray(), sub(x) x.Enabled = False) 
+0

Das ist gut, nicht ganz was ich brauche aber. Ich denke, dass Code nur eine Liste von Validatoren zurückgibt, aber was ich suche, ist alles mit einer ValidationGroup-Eigenschaft, die Textfelder, Schaltflächen, Validierungszusammenfassungen und ähnliches enthalten würde. –

+0

Sie können ein Prädikat in der Funktion GetControlsOfType() angeben, also tun Sie dies: userControl.GetControlsOfType (Of Control) (Unter (x) x.ValidationGroup = "myValidationGroup") – WiseGuyEh

+0

True. Ich müsste die Funktion für jeden Kontrolltyp aufrufen, der eine ValidationGroup-Eigenschaft haben könnte, die möglicherweise viele verschiedene Typen haben könnte. –

0

ich meinen Kopf gegen dieses Problem butting gerade jetzt, und kam mit einer alternativen Lösung, die nicht duck-Typisierung mit sich bringt:

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; 

Dies auch könnte eine Alternative sein:

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; 
} 
Verwandte Themen