在SharePoint Web部件中保留用于动态控件的用户输入

时间:2009-09-24 14:38:19

标签: c# sharepoint dynamic controls

使用解决方案在底部进行编辑

我之前看过一个类似的问题并尝试了这些建议,但我必须遗漏一些东西。我的基本问题是:我有一个选择框,用户可以在其中选择一个过滤器,该过滤器可能有也可能没有内置约束(要求用户输入更多数据,以便过滤器知道如何过滤)。由于不知道过滤器会存在多少约束,我试图动态加载它们并将它们添加到我拥有的占位符面板中。正确数量的约束加载得很好和花花公子,但是当用户输入文本并点击提交时,在页面重新加载后,没有任何值持续存在。这是适当的代码(如果需要我可以提供更多代码):

我将这些作为我的Web部件的类变量:

Panel constraintPanel;
HtmlInputText[] constraints;
Label[] constraintLabels = null;

在覆盖内部CreateChildControls我初始化面板:

constraintPanel = new Panel();

我在一个重写的OnPreRender中构建了动态输入框(注意:我听说有人说要在OnInit,OnLoad或OnPreRender中执行此操作,但OnPreRender是唯一一个不会导致整个Web部件错误的人出):

protected override void OnPreRender(EventArgs e)
{
    buildConstraints();
    base.OnPreRender(e);
}

private void buildConstraints()
{
    if (!viewSelect.SelectedValue.Equals(INConstants.NoFilterOption))
    {
        string[,] constraintList = docManager.GetFilterConstraints(viewFilterSelect.SelectedValue);
        if (constraintList != null)
        {
            this.constraints = new HtmlInputText[constraintList.Length / 2];
            this.constraintLabels = new Label[constraintList.Length / 2];
            for (int constraintCount = 0; constraintCount < constraintList.Length / 2; constraintCount++)
            {
                Label constraintLabel = new Label();
                constraintPanel.Controls.Add(constraintLabel);
                constraintLabel.Text = constraintList[constraintCount, 0];
                this.constraintLabels[constraintCount] = constraintLabel;

                HtmlInputText constraint = new HtmlInputText();
                constraintPanel.Controls.Add(constraint);
                constraint.ID = "constraint_" + constraintCount;
                constraint.MaxLength = 12;
                constraint.Style.Add("FONT-FAMILY", "Verdana");
                constraint.Style.Add("FONT-SIZE", "11");
                this.constraints[constraintCount] = constraint;
            }
        }
    }
}

然后最终在一个重写的RenderWebParts里面(注意:我也尝试循环遍历数组约束和constraintLabels来渲染控件,但它没有区别):

...
constraintPanel.RenderBeginTag(output); // not sure if this is needed
if (constraints != null && constraints.Length > 0)
{
    foreach (Control tempControl in constraintPanel.Controls)
    {
        if (tempControl is Label)
        {
            output.WriteLine("<tr>");
            output.WriteLine("<td width='2%' nowrap><font class='search-header'>");
            tempControl.RenderControl(output);
            output.WriteLine("&nbsp;");
        }
        else if (tempControl is HtmlInputText)
        {
            tempControl.RenderControl(output);
            output.WriteLine("</td>");
            output.WriteLine("<td width='*' nowrap></td>");
            output.WriteLine("</tr>");
        }
    }
}
constraintPanel.RenderEndTag(output); // not sure if this is needed
...

我感谢任何帮助,因为这真的让我发疯。

使用解决方案进行编辑:

我能够让它运转起来。我需要覆盖OnLoad事件并在try-catch块中包装我的调用。由于某种原因,初始页面加载在尝试运行时抛出异常,这导致整个页面不显示。我也忘了将constraintPanel添加到Controls列表中。

以下是OnLoad中的代码,以供参考:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    try
    {
        viewsBuildConstraints();
    }
    catch (Exception)
    {
    }
}

1 个答案:

答案 0 :(得分:2)

尝试使用INamingContainer接口标记您的webpart,并确保为所有控件提供ID。此外,HtmlInput COntrols没有我认为的viewstate,这会导致他们在回发后“忘记”输入。你能尝试使用实际的TextBox控件吗?