如何动态清除用户控件中的所有控件?

时间:2010-05-19 18:25:46

标签: .net asp.net user-controls controls clear

是否可以动态(并且通用)清除所有用户控件的子控件的状态? (例如,所有TextBox,DropDrownLists,RadioButtons,DataGrids,Repeater等 - 基本上任何具有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();

......但显然不存在。是否有任何简单的方法可以动态/通用地完成此操作?

7 个答案:

答案 0 :(得分:3)

我打算建议一个类似于Task的解决方案,除了(因为六个变量指出)我们需要将它实现为1个扩展方法,并且essentailly打开传入的控件的精确类型(即复制你发布的逻辑)你的问题)。

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()

答案 1 :(得分:2)

你可以做到

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

因为Controls只是一个列表,你可以在它上面调用Remove(),并将它传递给你想要删除的内容。

编辑:哦,对不起,我没有正确阅读。我不知道有办法做到这一点,也许这里有一个善于反思的人可以把它带到你想做的地方

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

或其他东西,把它变成一个新制作的组件。

答案 2 :(得分:1)

我还没有对它进行过测试,但清除用户控件的viewstate可能会有效。您也可以在用户控件上公开自定义方法:

用户控件:

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

页:

myUserControlInstance.Clear();

现在我还没有测试过。这可能只会清除UserControl容器的StateBag,而不是它的嵌套/子控件..如果上面的方法不起作用,你可以尝试使用递归来走下控制树来清除所有子节点的视图状态:

用户控件:

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();
    }
}

页:

myUserControlInstance.Clear();

只是一个想法。我没有测试过,但我认为理论上它可以工作。一个含义是在页面/控件生命周期中的正确位置调用Clear,否则它可能无效。

希望这有帮助!

答案 3 :(得分:1)

myUserControl.Controls.ToList().ForEach(c => myUserControl.Controls.Remove(c));

但是,请注意,因为您修改了迭代列表。这可能会导致一些奇怪的行为。

答案 4 :(得分:1)

在单个控件上设置EnableViewState="false"可能会为您节省工作,如果在这种情况下不会导致其他问题。

答案 5 :(得分:1)

Control.ClearChildViewState方法怎么样?

MSDN声明

  

删除所有服务器控件的子控件的视图状态信息。

我从未使用过这个。所以我不确定它是否会对你有所帮助。听起来不错,我认为:)

答案 6 :(得分:0)

为什么不按照你的建议去做:

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

应该这样做。