Pregunta

Necesito establecer la altura de cada cuadro de texto de mi formulario, algunos de los cuales están anidados dentro de otros controles.Pensé que podría hacer algo como esto:

private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)
{
    foreach (Control control in rootControl.Controls)
    {
        if (control.Controls.Count > 0)
        {
            // Recursively search for any TextBoxes within each child control
            foreach (TextBox textBox in FindTextBoxes(control))
            {
                yield return textBox;
            }
        }

        TextBox textBox2 = control as TextBox;
        if (textBox2 != null)
        {
            yield return textBox2;
        }
    }
}

Utilizándolo así:

foreach(TextBox textBox in FindTextBoxes(this))
{
    textBox.Height = height;
}

Pero, por supuesto, el compilador escupe su muñeco, porque para cada espera un IEnumerable en lugar de un IEnumerador.

¿Hay alguna manera de hacer esto sin tener que crear una clase separada con un ObtenerEnumerador() ¿método?

¿Fue útil?

Solución

Como le indica el compilador, debe cambiar su tipo de devolución a IEnumerable.Así es como funciona la sintaxis de rendimiento y retorno.

Otros consejos

Solo para aclarar

private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)

Cambios a

private static IEnumerable<TextBox> FindTextBoxes(Control rootControl)

Eso debería ser todo :-)

Si devuelve IEnumerator, será un objeto enumerador diferente cada vez que llame a ese método (actuando como si restableciera el enumerador en cada iteración).Si devuelve IEnumerable, entonces un foreach puede enumerar según el método con la declaración de rendimiento.

// Generic function that gets all child controls of a certain type, 
// returned in a List collection
private static List<T> GetChildTextBoxes<T>(Control ctrl) where T : Control{
    List<T> tbs = new List<T>();
    foreach (Control c in ctrl.Controls) {
        // If c is of type T, add it to the collection
        if (c is T) { 
            tbs.Add((T)c);
        }
    }
    return tbs;
}

private static void SetChildTextBoxesHeight(Control ctrl, int height) {
    foreach (TextBox t in GetChildTextBoxes<TextBox>(ctrl)) {
        t.Height = height;
    }
}

Si se le proporciona un enumerador y necesita usarlo en un bucle para cada uno, puede usar lo siguiente para ajustarlo:

static public class enumerationHelper
{
    public class enumeratorHolder<T>
    {
        private T theEnumerator;
        public T GetEnumerator() { return theEnumerator; }
        public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;}
    }
    static enumeratorHolder<T> toEnumerable<T>(T theEnumerator) { return new enumeratorHolder<T>(theEnumerator); }
    private class IEnumeratorHolder<T>:IEnumerable<T>
    {
        private IEnumerator<T> theEnumerator;
        public IEnumerator<T> GetEnumerator() { return theEnumerator; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; }
        public IEnumeratorHolder(IEnumerator<T> newEnumerator) { theEnumerator = newEnumerator; }
    }
    static IEnumerable<T> toEnumerable<T>(IEnumerator<T> theEnumerator) { return new IEnumeratorHolder<T>(theEnumerator); }
}

El toEnumerable El método aceptará cualquier cosa que o consideraría un tipo de devolución aceptable de GetEnumerator, y devolver algo que pueda usarse en foreach.Si el parámetro es un IEnumerator<> la respuesta será una IEnumerable<T>, aunque llamando GetEnumerator Una vez, es probable que se obtengan malos resultados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top