【问题标题】:How can I dynamically clear all controls in a user control?如何动态清除用户控件中的所有控件?
【发布时间】:2011-02-21 12:48:03
【问题描述】:

是否可以动态(一般地)清除用户控件的所有子控件的状态? (例如,它的所有 TextBoxes、DropDrownLists、RadioButtons、DataGrids、Repeaters 等——基本上任何具有 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();

...但显然不存在。有没有简单的方法来动态/通用地完成这个?

【问题讨论】:

  • 也许,您只需要一个简单的重定向?

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


【解决方案1】:

我打算提出一个类似于 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()

【讨论】:

  • 我接受了这个答案,因为我认为这与我的初衷很接近。不幸的是,似乎没有完全动态的方式来清除所有子控件。
【解决方案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();
}

什么的,把它变成一个新制作的组件。

【讨论】:

  • 我认为迈克尔希望清除每个控件中的值/状态。不是集合中的控件本身。
  • KP:正确。我不想删除控件,只是清除它们(例如,清除 TextBox 文本值、清除 DropDownList 中的选定项、清除 DataGrid/Repeater 的内容等)。
  • Nilbert:没有问题,无论如何感谢您的意见。我喜欢你用反射概念去的地方;这就是我想知道的类型。
【解决方案3】:

我还没有测试过,但是清除用户控件的视图状态可能会起作用。您也可以在用户控件上公开自定义方法:

用户控制:

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,否则它可能不起作用。

希望这会有所帮助!

【讨论】:

  • 嗯..我自己测试过,似乎没有用..我会再玩一会儿,因为我喜欢这个概念..
  • 我开枪了。 ViewState 不是公共属性,因此您不能只清除它以进行控制。我喜欢在另一个答案中讨论的递归想法......我会留下这个答案,即使它不会工作,以防其他人有同样的想法......
【解决方案4】:
myUserControl.Controls.ToList().ForEach(c => myUserControl.Controls.Remove(c));

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

【讨论】:

  • 减 1,因为删除控件与原始问题无关。
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    Control.ClearChildViewState 方法呢?

    MSDN 状态

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

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

    【讨论】:

    • 听上去应该是完美的解决方案,可惜行不通。
    【解决方案7】:

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

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

    应该可以的。

    【讨论】:

    • 所以在foreach中每次调用Clear()都会调用静态Control.Clear()?因此,要使其正常工作,您将回到 Control.Clear() 中的“if (c is TextBox)...”?确实,那不是一个好的解决方案。
    • 正确。 c 静态类型为 Control,因此扩展方法将查找 Control
    猜你喜欢
    • 2018-12-21
    • 2012-01-09
    • 2018-03-24
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2017-01-10
    相关资源
    最近更新 更多