开发者

How to remove all children in HtmlElement with Silverlight/C#

So I have this Silverlight application that calls some reports(.rdlc) via HTML form submit. This form is universal, so I use it to call all reports with it.

Now I want to clear the input elements in it everytime the form has been submited.

So I want a clear form everytime I want to call a new report with no children in it.

Can anyone explain why this is not working when there are more than 5(or any larger amount of inputs) inputs in the form?

    public static void RemoveInputsFromForm(HtmlElement Form)
    {
        if (HtmlPage.Document.GetElementById(Form.Id) != null)
        {
            foreach (HtmlElement element in Form.Children)
            {
                if (element.Id != string.Empty)
                {
                    element.Parent.RemoveChild(element);
                }
            }
        }
    }

The form has it's ID and every input has an ID, it removes some inputs randomly, others stay in the form.

This is the method that inserts the input elements into that form:

public static void AddInputToForm(HtmlElement Form, string Name, object Data)
    {
        if (Data != null && Data.ToString() != string.Empty)
        {
            var input = HtmlPage.Document.CreateElement("input");
            input.SetProperty("type", "hidden");
            input.SetProperty("value", Data.ToString());
            input.SetProperty("name", Name);
            input.SetProperty("id", Name);
            Form.AppendChild(input);
        }
    }

This is the method that I use now to remove form children, it is the same as AddInputToForm method only that it removes inputs

 public static void RemoveInputFromForm(HtmlElement Form, string Name)
    {

        if (HtmlPage.Document.GetElementById(Name) != null)
        {
            Form.RemoveChild(HtmlPage.Document.GetElementById(Name));
        }

    }

This is the method that gets开发者_如何转开发 my form

  public static HtmlElement GetForm(string formUrl)
    {
        //in the html that holds the silverlight object, you must have a form named "reportform"
        //<form id="reportform" action="" method="post" target="_blank" style="visibility: collapse" />
        HtmlElement functionReturnValue = null;


        //set form
        functionReturnValue = HtmlPage.Document.GetElementById("reportform");

        //set form action
        functionReturnValue.SetProperty("action", formUrl);


        return functionReturnValue;
    }

To reproduce the code (SomeElement is an object with string properties):

           //get form
            var Form = GetForm(ApplicationUrl + @"Reports\Report.aspx");

            //add parameters to form
            AddInputToForm(Form, "id1", SomeElement.Id1Value);
            AddInputToForm(Form, "id2", SomeElement.Id2Value);
            AddInputToForm(Form, "id3", SomeElement.Id3Value);
            AddInputToForm(Form, "id4", SomeElement.Id4Value);
            AddInputToForm(Form, "id5", SomeElement.Id5Value);
            AddInputToForm(Form, "id6", SomeElement.Id6Value);
            AddInputToForm(Form, "id7", SomeElement.Id7Value);
            AddInputToForm(Form, "id8", SomeElement.Id8Value);
            AddInputToForm(Form, "id9", SomeElement.Id9Value);

            //submit form
            Form.Invoke("submit");

            //clean report
            RemoveInputFromForm(Form, "id1");
            RemoveInputFromForm(Form, "id2");
            RemoveInputFromForm(Form, "id3");
            RemoveInputFromForm(Form, "id4");
            RemoveInputFromForm(Form, "id5");
            RemoveInputFromForm(Form, "id6");
            RemoveInputFromForm(Form, "id7");
            RemoveInputFromForm(Form, "id8");
            RemoveInputFromForm(Form, "id9");

So you see I have to remove every child I added with as many calls as there are inputs in the form, I would like to have only one call and clean that form.

Thanks in advance to any given solution.


You should never add or remove elements while inside a foreach loop, as the collection changes and invalidates the loop. Rather add all items to be removed in a separate list and then remove them in a second loop. (I haven't tested it because I do not have relevant sample code, but this is a common mistake with foreach loops.)

List<HtmlElement> toRemove = new List<HtmlElement>();
foreach (HtmlElement element in Form.Children)
{
    if (element.Id != string.Empty)
    {
        toRemove.Add(element);
    }
}
foreach (HtmlElement element in toRemove)
{
    Form.RemoveChild(element);
}

Alternatively, using your second approach, you can always add all your IDs to a list, and then add a RemoveAllFormInputs() method which loops over these elements.


Peet has provided the correct answer, however some may prefer a Linq based approach that slims the code a litte.

foreach (HtmlElement element in Form.Children
                                    .OfType<HtmlElement>
                                    .Where(e => !String.IsNullOrEmpty(e.Id))
                                    .ToList() )
{
    Form.RemoveChild(element);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜