Οκ, καλημέρα ! ... με κώδικα και καφέ. (
yes, I really should get a life ... )
Βασική κλάσση, ένας control iterator, οποίος δέχεται ως constructor parameters ένα enumerable collection απο Control instances, καθώς και ένα delegate, ο οποίος μπορεί να δείχνει σε μια ή περισσότερες μεθόδους οι οποίες κάνουν process κάθε control στο collection.
(
Εκμεταλλεύομαι το γεγονός ότι ένας delegate είναι στην ουσία ένας function pointer σε μιά μέθοδο, αλλά στο .NET δεν υπάρχει διαφορά μεταξύ single ή multi delegates.
Έτσι, θα μπορούσες να περάσεις έναν multi delegate, και θα εκτελούσε κάθε μια απο τις μεθόδους στις οποίες δείχνει, και μάλιστα στη σειρά που του τις έδωσες )
Λίγος κώδικας:
using System;
using System.Web.UI;
using System.Collections.Generic;
namespace ControlIterator
{
/// <summary>
/// Summary description for
ControlIterator
/// </summary>
public class ControlIterator
{
/// <summary>
/// Defines the footprint
of a method that will retrieve
/// a collection of
controls to iterate on, from a specified
/// web form
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
public delegate void ProcessControlMethod(Control control);
///
<summary>
/// Initialize from a
collection of controls ...
/// </summary>
/// <param name="controls"></param>
public ControlIterator(IEnumerable<Control> controls, ProcessControlMethod
processor) {
this.Controls = controls;
this.ProcessControlDelegate = processor;
}
#region lookup controls & process methods / properties
private IEnumerable<Control>
m_Controls = null;
protected IEnumerable<Control> Controls {
get{
if (null == m_Controls)
throw new
NullReferenceException("Controls
to iterate have not been initialized");
return m_Controls;
}
set{
if (null == value)
throw new
ArgumentNullException("Controls
to iterate cannot be initialized to null");
m_Controls
= value;
}
}
private ProcessControlMethod
m_ProcessControlDelegate;
/// <summary>
/// Retrieves / sets in a
type-safe way the procesor method for each node in the iteration
/// </summary>
protected ProcessControlMethod
ProcessControlDelegate {
get {
if (null ==
m_ProcessControlDelegate)
throw new
NullReferenceException("ProcessControlDelegate
has not yet been initalized");
return m_ProcessControlDelegate;
}
set {
if (null == value)
throw new
ArgumentNullException("ProcessControlDelegate
cannot be initialized to null");
// I could / should (??) be checking for multiplicity here,
but perhaps it's actually a feature !!!
m_ProcessControlDelegate
+= value;
}
}
/// <summary>
/// Iterates through the
controls array, and proceses each one of them with the given
/// delegate
/// </summary>
public void Iterate()
{
foreach (Control ctrl
in this.Controls)
this.ProcessControlDelegate(ctrl);
}
#endregion
}
}
Δεν κάνει κάτι σπουδαίο ... απλώς είναι wrapper γύρω απο το functionality που χρειάζεται για το iteration / function calling.
Και λίγος κώδικας στη σελίδα τώρα:
using securityIter =
ControlIterator.ControlIterator;
public partial class _Default :
System.Web.UI.Page
{
private Control[]
ControlsToValidate {
get {
return new Control[2] { this.TextBox1,
this.Button1 };
}
}
protected void
Page_Load(object sender, EventArgs e)
{
securityIter iterator = new
securityIter(this.ControlsToValidate,
delegate(Control
ctrl) {
if (ctrl is TextBox) {
((TextBox)ctrl).Enabled = false;
}
else if (ctrl is Button) {
((Button)ctrl).Visible = false;
}
}
);
iterator.Iterate();
}
}
Piece of cake ??? :D
Καλά, παραβλέψτε τον anonymous delegate - το έκανα προς χάρην ευκολίας, και απλώς για να δείξω ότι γίνεται.
Το βασικό concept είναι οτι θα είχα τον iterator και το initialization & iteration σε κάποια base κλάσση για όλες τις σελίδες / φόρμες μου, και το εκάστοτε subclass θα υλοποιούσε απλώς τη μέθοδο που επιστρέφει τα controls to validate (άτυχο όνομα), και ίσως και τον / τους delegates που κάνουν το processing. Επίσης, το αν θα κάνει disable / not visible τα controls θα μπορούσες να το ελέγχεις με τύποις declarative τρόπο, έχοντας attributes πάνω στα controls.
Και τελειώνω με μια πολύ αγαπημένη μου φράση ...
οι delegates ΔΕΝ ΕΙΝΑΙ ΑΠΛΩΣ EVENT HANDLERS !!!!
Άντε καλημέρα μας !
Angel
O:]