我有一个asp.net仪表板站点,允许用户从下拉列表中加载HTML模板。页面上有多种类型的DevExpress组件,包括ASPxDockPanel。如果用户更改了模板,我会收到dockpanel已经存在的错误,我想要包含一个递归函数,如下面的函数,检查页面上是否存在任何ASPxDockPanel,如果它们存在则删除它们。这只适用于第一个停靠面板然后炸弹。我认为这是因为在循环遍历时无法修改可枚举的控件集。如何循环控件并在运行时删除停靠面板?
protected void LoadTableTemplate(string selectedTemplate, int currentMode)
{
FindAllDockPanels(this);
}
public void FindAllDockPanels(Control ctrl)
{
if (ctrl != null)
{
foreach (Control control in ctrl.Controls)
{
if (control is ASPxDockPanel)
{
ctrl.Controls.Remove(control);
control.Dispose();
}
FindAllDockPanels(control);
}
}
}
答案 0 :(得分:1)
使用临时集合,如下所示:
public void FindAllDockPanels(Control ctrl) {
if (ctrl != null) {
List<Control> remove = new List<Control>();
foreach (Control control in ctrl.Controls) {
if (control is ASPxDockPanel) {
remove.Add( control );
}
}
foreach(Control control in remove) {
control.Controls.Remove( control );
control.Dispose(); // do you really need to dispose of them?
}
FindAllDockPanels(control);
}
}
如果您经常这样做,可能值得将这些“DelayedDelete”操作移动到扩展方法,如下所示:
public static void DelayedRemove<T>(this IEnumerable<T item> collection, T itemToRemove) {
// add it to a private static dictionary bound to the `collection` instance.
}
public static void DelayedRemoveFinish(this IEnumerable<T item> collection) {
// empty the private static dictionary in here
}
然后你会像这样使用它:
public void FindAllDockPanels(Control ctrl) {
if (ctrl != null) {
foreach (Control control in ctrl.Controls) {
if (control is ASPxDockPanel) control.Controls.DelayedRemove( control );
}
control.Controls.DelayedRemoveFinish();
FindAllDockPanels(control);
}
}
更清洁,不是吗? :)