Как я могу динамично очистить все средства управления в пользовательском элементе управления?

Действительно ли возможно динамично (и в общем) очищают состояние всех дочерних элементов управления пользовательского элемента управления? (например, все его TextBoxes, DropDrownLists, RadioButtons, DataGrids, Повторители, и т.д. - в основном что-либо, что имеет ViewState),

Я стараюсь не делать что-то вроде этого:

foreach (Control c in myUserControl.Controls)
{
    if (c is TextBox)
    {
        TextBox tb = (TextBox)c;
        tb.Text = "";
    }
    else if (c is DropDownList)
    {
        DropDownList ddl = (DropDownList)c;
        ddl.SelectedIndex = -1;
    }
    else if (c is DataGrid)
    {
        DataGrid dg = (DataGrid)c;
        dg.Controls.Clear();
    }

    // etc.

}

Я ищу что-то вроде этого:

foreach (Control c in myUserControl.Controls)
    c.Clear();

... но очевидно который не существует. Там какой-либо простой способ состоит в том, чтобы выполнить это динамично/в общем?

6
задан Michael 19 May 2010 в 18:25
поделиться

7 ответов

Я собирался предложить решение, похожее на решение Task, но (как указывает sixlettervariables) мы должны реализовать его как 1 метод расширения и по сути переключать точный тип переданного элемента управления (т.е. копировать вашу логику, которую вы опубликовали в своем вопросе).

public static class ControlExtensions
{
    public static void Clear( this Control c )
    {
        if(c == null) {
            throw new ArgumentNullException("c");
        }
        if (c is TextBox)
        {
            TextBox tb = (TextBox)c;
            tb.Text = "";
        }
        else if (c is DropDownList)
        {
            DropDownList ddl = (DropDownList)c;
            ddl.SelectedIndex = -1;
        }
        else if (c is DataGrid)
        {
            DataGrid dg = (DataGrid)c;
            dg.Controls.Clear();
        }
        // etc....
    }
}

Это не особенно элегантный метод, но ваш код в вашей странице/контроле теперь более лаконичный

foreach (Control c in myUserControl.Controls) {
    c.Clear();
}

и вы, конечно, можете теперь вызывать control.Clear() в любом другом месте вашего кода.

3
ответ дан 10 December 2019 в 02:43
поделиться

Вы можете сделать

foreach (Control c in myUserControl.Controls) {
    myUserControl.Controls.Remove(c);
}

Поскольку Controls - это просто список, вы можете вызвать для него Remove (), передав ему то, что вы хотите удалить.

РЕДАКТИРОВАТЬ: Ой, извините, я неправильно прочитал. Я не знаю, как это сделать, может быть, кто-то здесь, кто хорошо разбирается в Reflection, сможет сделать это там, где вы могли бы сделать вроде

foreach (Control c in myUserControl.Controls) {
    c = new c.Type.GetConstructor().Invoke();
}

или что-то в этом роде, превратить его в недавно созданный компонент.

2
ответ дан 10 December 2019 в 02:43
поделиться

Я не тестировал это, но очистка состояния просмотра для пользовательского элемента управления может работать. Вы также можете предоставить собственный метод для пользовательского элемента управления:

usercontrol:

public void Clear()
{
    this.ViewState.Clear();
}

page:

myUserControlInstance.Clear();

Опять же, я не тестировал. Возможно, это очистит только StateBag для контейнера UserControl, а не его вложенные / дочерние элементы управления. Если вышеуказанное не работает, вы можете попробовать использовать рекурсию, чтобы пройти вниз по дереву элементов управления, чтобы очистить состояние просмотра для все дети:

usercontrol:

public void Clear()
{
    ClearViewState(this.Controls);
}

private void ClearViewState(ControlCollection cc)
{
    foreach(Control c in cc)
    {
        if(c.HasControls())
        {
            //clear the child controls first
            ClearViewState(c.Controls);
        }        

        //then clear the control itself
        c.ViewState.Clear();
    }
}

page:

myUserControlInstance.Clear();

Просто идея. Я не тестировал, но думаю, что теоретически это может сработать. Одним из последствий может быть вызов Clear в правильном месте жизненного цикла страницы / элементов управления, иначе это может не сработать.

Надеюсь, это поможет!

1
ответ дан 10 December 2019 в 02:43
поделиться

Настройка EnableViewState = "false" для отдельных элементов управления может сэкономить вам работу, если в данном случае это не вызовет у вас других проблем.

1
ответ дан 10 December 2019 в 02:43
поделиться

Почему бы не сделать так, как вы предлагаете:

foreach (Control c in myUserControl.Controls)
    c.Clear();

А затем реализовать Clear:

public static class UserController
{
    public static void Clear( this Control c )
    {
        c.Controls.Clear();
    }

    public static void Clear( this TextBox c )
    {
        c.Text = String.Empty;
    }
}

Это должно сработать.

0
ответ дан 10 December 2019 в 02:43
поделиться
myUserControl.Controls.ToList().ForEach(c => myUserControl.Controls.Remove(c));

Однако будьте осторожны, поскольку вы изменяете итерирующий список. Это может привести к странному поведению.

1
ответ дан 10 December 2019 в 02:43
поделиться

А как насчет метода Control.ClearChildViewState?

MSDN states

Удаляет информацию о состоянии представления для всех дочерних элементов управления сервера.

Однако я никогда не использовал этот метод. Поэтому я не уверен, поможет ли он вам. Хотя звучит неплохо, я думаю :)

1
ответ дан 10 December 2019 в 02:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: