C# 在ASP.NET的代码隐藏中访问用户控件

C# 在ASP.NET的代码隐藏中访问用户控件,c#,asp.net,user-controls,C#,Asp.net,User Controls,这个问题是针对ASP.NET专家的。我快发疯了 我继承了一个ASP.NET Web窗体应用程序。此应用程序使用复杂的 嵌套用户控件的结构。虽然很复杂,但在这种情况下似乎确实有必要。 无论如何,我有一个使用单个UserControl的页面。我们称之为UserControl 根控制。此UserControl的定义如下: widget.ascx <%@ Control Language="C#" AutoEventWireup="true" CodeFile="widget.ascx.cs" I

这个问题是针对ASP.NET专家的。我快发疯了

我继承了一个ASP.NET Web窗体应用程序。此应用程序使用复杂的 嵌套用户控件的结构。虽然很复杂,但在这种情况下似乎确实有必要。 无论如何,我有一个使用单个UserControl的页面。我们称之为UserControl 根控制。此UserControl的定义如下:

widget.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="widget.ascx.cs" Inherits="resources_userControls_widget" %>
<div>
  <asp:Panel ID="bodyPanel" runat="server" />
</div>
<uc:Widget ID="myWidget" runat="server"  Source="/userControls/widgets/info.ascx" />
在我的应用程序中,我以以下方式使用widget.ascx: page.aspx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="widget.ascx.cs" Inherits="resources_userControls_widget" %>
<div>
  <asp:Panel ID="bodyPanel" runat="server" />
</div>
<uc:Widget ID="myWidget" runat="server"  Source="/userControls/widgets/info.ascx" />
请注意info.ascx是如何设置为本例中要加载的UserControl的。在这种情况下,这种方法是必要的。我已经删除了一些无关的代码,这些代码使我有理由关注这个问题。无论如何,在info.ascx.cs中,我有以下内容:

info.ascx.cs

public partial class resources_userControls_widget : System.Web.UI.UserControl
{
    private string source = string.Empty;
    public string Source
    {
        get { return source; }
        set { source = value; }
    }

    private string parameter1 = string.Empty;
    public string Parameter1
    {
        get { return parameter1; }
        set { parameter1 = value; }
    }

    private DataTable records = new DataTable();
    public DataTable Records
    {
        get { return records; }
        set { records = value; }
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        UserControl userControl = LoadControl(source) as UserControl;
        if (parameter1.Length > 0)
            userControl.Attributes.Add("parameter1", parameter1);
        bodyPanel.Controls.Add(userControl);
    }

    private void InsertUserControl(string filename)
    {
    }
}
protected void Page_Load(object sender, EventArgs e)
{
  DataTable table = GetData();
  myWidget.Records = table;
}
protected void Page_Load(object sender, EventArgs e)
{
  // Here's the problem
  // this.Parent.Parent is a widget.ascx instance.
  // However, I cannot access the Widget class. I want to be able to do this
  // Widget widget = (Widget)(this.Parent.Parent);
  // DataTable table = widget.Records;
}
我确实需要从父用户控件获取“Records”属性的值。不幸的是,我似乎无法从我的代码中访问Widget类。是否有一些关于编译时用户控件可见性的规则我不知道?如何从info.ascx.cs的代码隐藏中访问Widget类


谢谢大家!

在您的情况下,最好使用一些服务器对象,如ViewState或Session。将其填入页面上的DataTable中,并将其放入info.ascx用户控件上的page_load event handler中。

首先,您需要创建一个接口并将其实现到Widget用户控件类

比如说,

public interface IRecord
{
    DataTable Records {get;set;}
} 

public partial class resources_userControls_widget : System.Web.UI.UserControl, IRecord
{
 ...
}
在Info.ascx.cs的代码隐藏中

protected void Page_Load(object sender, EventArgs e)
{
  // Here's the problem
  // this.Parent.Parent is a widget.ascx instance.
  // However, I cannot access the Widget class. I want to be able to do this
  // Widget widget = (Widget)(this.Parent.Parent);
  // DataTable table = widget.Records;

  IRecord record=this.Parent.Parent;
  DataTable table = widget.Records;
}

好奇的是,这个.Parent.Parent.ToString()报告的是什么?Parent.Parent.ToString()显示了我试图获取的类(小部件)的名称。这就是这一切的奇怪之处。在运行时,我可以很好地看到类名。然而,在开发/编译期间,小部件在IntelliSense中不可用。如果我只是使用它,忽略IntelliSense,编译就会失败。非常流畅。我会尝试一下,如果成功的话,我会相信这篇文章。但我喜欢这个主意。对不起,伙计们,但IRecord record=this.Parent.Parent;-这是一个愚蠢的错误,因为父控件有一个控件类型,不能实现任何自定义接口。@Phone Developer-我错了-直到您更改控件层次结构时它才起作用。如果添加母版页或更改现有的控件层次结构,则会出现运行时错误。但这取决于你。