【问题标题】:Accessing usercontrols in code-behind in ASP.NET在 ASP.NET 的代码隐藏中访问用户控件
【发布时间】:2011-10-19 14:48:08
【问题描述】:

这个问题是针对 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>

widget.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)
    {
    }
}

在我的应用程序中,我通过以下方式使用 widget.ascx: page.aspx

<uc:Widget ID="myWidget" runat="server"  Source="/userControls/widgets/info.ascx" />

page.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
  DataTable table = GetData();
  myWidget.Records = table;
}

请注意 info.ascx 在这种情况下是如何设置为我们要加载的 UserControl 的。在这种情况下,这种方法是必要的。我已经删除了证明它可以专注于问题的无关代码。无论如何,在 info.ascx.cs 我有以下内容:

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;
}

我确实需要从 Parent 用户控件中获取“Records”属性的值。不幸的是,我似乎无法从我的代码隐藏中访问 Widget 类。编译时是否有一些我不知道的关于 UserControl 可见性的规则?如何从 info.ascx.cs 的代码隐藏中访问 Widget 类?

谢谢!

【问题讨论】:

  • 只是好奇,this.Parent.Parent.ToString() 报告是什么?
  • Parent.Parent.ToString() 显示我要获取的类的名称(小部件)。这就是这一切的奇怪之处。在运行时,我可以很好地看到类名。但是,在开发/编译期间,小部件在 IntelliSense 中不可用。如果我只是使用它,而忽略 IntelliSense,编译会失败。

标签: c# asp.net user-controls


【解决方案1】:

首先你需要创建一个接口并将其实现到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;
}

【讨论】:

  • 非常漂亮。我会试一试,如果它有效,我会相信这篇文章。但我喜欢这个主意。
  • 对不起,伙计们,但是 IRecord record=this.Parent.Parent; - 这很愚蠢,因为 Parent 有一个 Control 类型并且不能实现任何自定义接口。
  • @电话开发人员-我错了-直到您更改控制层次结构时才起作用。如果您添加 MasterPage 或更改现有的控件层次结构,您将收到运行时错误。但这取决于你。
【解决方案2】:

在您的情况下,最好使用一些服务器对象,例如 ViewState 或 Session。在页面上的 DataTable 中填充它,并在 info.ascx 用户控件上的 Page_load 事件处理程序中获取它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2012-07-10
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多