从app_code类中访问服务器控件

时间:2010-12-26 22:48:06

标签: c# asp.net

我的问题是访问位于default.aspx中的服务器控件(列表框)。

我希望在Functions.cs中访问此控件(此类位于App_Code文件夹中)。

我的页面结构是:

  • 包含1个内容持有者的1个母版页
  • Default.aspx(所有控件都在内容占位符内)
  • Functions.cs(位于App_Code中)

现在,当我尝试填充列表框元素时,我得到错误“对象引用未设置为对象的实例。”

我试图获得对此控件的访问权限:(此代码位于App_Code中的Functions.cs中)。 这基本上显示了列表框中位于xml文件中的一些项目

private static string file = HttpContext.Current.Server.MapPath("~/App_Data/Questions.xml");

public static void ListItems()
{
    XmlDocument XMLDoc = new XmlDocument();
    XMLDoc.Load(file); 
    XPathNavigator nav = XMLDoc.CreateNavigator();

    XPathExpression expr;
    expr = nav.Compile("/root/file/naam");
    XPathNodeIterator iterator = nav.Select(expr);

    //ATTEMPT to get access to ServerControl(listbox)
    Page page = (Page)HttpContext.Current.Handler;
    ListBox test = (ListBox)page.FindControl("lbTest"); //control is called lbTest in Default.aspx

    test.Items.Clear();

    while (iterator.MoveNext())
    {
        test.Items.Add(iterator.Current.Value);
    }
}

default.apx文件中的代码

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterFile.master" AutoEventWireup="true" CodeFile="default.aspx.cs" Inherits="default" Debug="true" %>

<%@ MasterType TypeName="Master" %>

<asp:Content ID="Content1" ContentPlaceHolderID="cphContent" Runat="Server" >

    <asp:MultiView ID="mvTest" runat="server" >

        <asp:View ID="vCollection" runat="server">
            <asp:ListBox ID="lbTest" runat="server" CssClass="listbox" ></asp:ListBox>
        </asp:View>


    </asp:MultiView>

</asp:Content>

masterfile本身只有1个占位符。

然后我调用Default.aspx.cs文件中的ListItems函数

protected void Page_Load(object sender, EventArgs e)
{    
    Functions.ListItems();
}

2 个答案:

答案 0 :(得分:2)

FindControl不会搜索嵌套控件。

You need to search recursively

private Control FindControlRecursive(Control rootControl, string controlID) {
    if (rootControl.ID == controlID) return rootControl;

    foreach (Control child in rootControl.Controls) {
        var match = FindControlRecursive(child, controlID);
        if (match != null) return match;
    }
    return null;
}

然而,你的设计太过分了 你应该考虑一个不涉及这个的设计。

例如,您可以将ListBox作为参数传递,将方法移动到页面类,或者创建一个带有虚拟属性的基页面类来获取ListBox。

答案 1 :(得分:1)

您应该将想要填充项目的控件传递给您的函数。

Function.cs:

public static void ListItems(ListBox test)
{
     //same as what you had before, minus the
     //ATTEMPT to get access to ServerControl(listbox)
     //lines
}

代码隐藏:

protected void Page_Load(object sender, EventArgs e)
{
    Functions.ListItems(lbTest); //pass your control in here...
}