ASP.Net c# - 如何从 App_Code 类中实例化 WebUserControl 的实例?

发布于 2024-10-16 12:43:23 字数 2467 浏览 2 评论 0原文

阿罗哈,

我有一个自定义控件,我需要从类中实例化该控件并将其添加到页面。我的类有一个函数,我将 Page 传递给该函数,以便我可以访问页面上的控件。我正在使用此方法添加标准 ASP 控件,并且一切都按预期工作。我的问题是自定义控件的类型是否已定义?

我在此处阅读以移动.cs 从控件复制到 App_Code 文件夹中,但是当我这样做时,它不会编译,因为它看不到 ascx 中的控件有效。例如,我得到CS0103:名称“litTest”在当前上下文中不存在。因此,由于它们是部分类,我在 App_Code 文件夹中创建了一个新的空部分类,并单独保留了控件的 .cs 文件。

好吧,它以这种方式编译,但是当我将控件添加到 Page.controls 集合时,我在页面上没有看到任何应该在的位置。例如,我将 TEST 添加到 ascx 文件的底部,但我在页面上看不到它。此外,该控件具有我需要设置的变量,而在使用空分部类时我无法访问这些变量。

我知道我想要做的事情适用于标准控件,为什么我似乎无法使用自定义控件来实现此操作?

App_Code 文件夹中的我的部分类:

public partial class CustomControlClass : System.Web.UI.UserControl
{

}

用户控件的部分类:

public partial class CustomControlClass : System.Web.UI.UserControl
{
    private int _myValue= -1;
    public int myValue
    {
        get { return _myValue; }
        set { _myValue= value; }
    }
    protected void Page_Init(object sender, EventArgs e)
    {
        litTest.Text = "TEST";
    }
}

我的用户控件 ascx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomControlClass.ascx.cs" Inherits="CustomControlClass" %>
<asp:Literal ID="litTest" runat="server"></asp:Literal>
TEST

我的 App_Code 类:

public class MyClass
{
    public static void doWork(Page Ctrl)
    {
        CustomControlClass c = new CustomControlClass();
        //c.myValue = 1;  // Wont compile with this line
        Ctrl.Controls.Add(c);

        Literal l = new Literal();
        l.Text = "HELLO";
        Ctrl.Controls.Add(l);
    }
}

页面输出上根本没有“TEST”一词。 HELLO 这个词显示得很好。我尝试从页面 LoadInitPreInit 回调中调用 MyClass.doWork(),所有结果导致了那位女士的事情。

更新:

正如Minh Nguyen建议的那样,我可以使用Ctrl.LoadControl("~/Controls/CustomControlClass.ascx");来加载控件,但是我无法将其转换为自己的类型,我必须将其分配为控件类型:

Control c= Ctrl.LoadControl("~/Controls/CustomControlClass.ascx");

这样做可以让我将控件添加到页面并使其按预期工作。缺点是我无法访问任何控件属性。为了解决这个问题,我正在这样做:

c.GetType().GetProperty("myValue").SetValue(c, 1, null);

这可行,但我不确定它的使用成本有多高。我希望我可以直接投射控件,但是当我尝试时出现错误。

我暂时不回答这个问题,看看是否还有其他选择。

Aloha,

I have a custom control that I need to instantiate from within a class and add to a page. My class has a function that I pass the Page to so i have access to the controls on the page. I'm using this method to add standard ASP controls already and everything it working as expected. My problem is that the type for the custom control is know defined?

I read here to move the .cs from the control into the App_Code folder but when I do that it won't compile as it doesn't see the controls in the ascx as valid. For example I get CS0103: The name 'litTest' does not exist in the current context. So as they are partial classes I created a new empty partial class in the App_Code folder and left the control's .cs file alone.

Well it compiles this way but when I add the control to the Page.controls collection, I dont see anything on the page where it should be. For example I added TEST to the bottom of the ascx file, it I dont see it on the page. Additionally the control has variables that I need to set that I don't have access to when using the empty partial class.

I know that what I am trying to do works with standard controls, why can't I seem to make this work with a custom control?

My partial class in the App_Code folder:

public partial class CustomControlClass : System.Web.UI.UserControl
{

}

My partial class in for the user control:

public partial class CustomControlClass : System.Web.UI.UserControl
{
    private int _myValue= -1;
    public int myValue
    {
        get { return _myValue; }
        set { _myValue= value; }
    }
    protected void Page_Init(object sender, EventArgs e)
    {
        litTest.Text = "TEST";
    }
}

My user control ascx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomControlClass.ascx.cs" Inherits="CustomControlClass" %>
<asp:Literal ID="litTest" runat="server"></asp:Literal>
TEST

My App_Code class:

public class MyClass
{
    public static void doWork(Page Ctrl)
    {
        CustomControlClass c = new CustomControlClass();
        //c.myValue = 1;  // Wont compile with this line
        Ctrl.Controls.Add(c);

        Literal l = new Literal();
        l.Text = "HELLO";
        Ctrl.Controls.Add(l);
    }
}

The page output does not have the word TEST on it at all. The word HELLO shows up just fine. I've tried calling the MyClass.doWork() from the pages Load, Init and PreInit callbacks, all result in the dame thing.

Update:

As Minh Nguyen suggested I can use Ctrl.LoadControl("~/Controls/CustomControlClass.ascx"); to load the control but I can not cast it as its own type I have to assign it as a Control type:

Control c= Ctrl.LoadControl("~/Controls/CustomControlClass.ascx");

Doing this will let me add the control to the page and have it work as expected. The down side is that I have no access to any of the controls properties. To solve this i am doing this:

c.GetType().GetProperty("myValue").SetValue(c, 1, null);

This works, but I'm not sure how expensive that it to use. I wish I could just cast the control but I get an error when I try.

I'm leaving this unanswered for a bit to see if there are any other options.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掩于岁月 2024-10-23 12:43:23

使用

CustomControlClass c = (CustomControlClass)Ctrl.LoadControl("~/VirtualPathToASCX/CustomControlClass.ascx");

而不是

CustomControlClass c = new CustomControlClass();

更新:修复强制转换错误,

//LoadControl
ASP.customcontrolclass_ascx c = (ASP.customcontrolclass_ascx)this.LoadControl("~/Controls/CustomControlClass.ascx");
//set myValue
c.myValue = 3;

您在 VS AutoComplete 列表中看不到 ASP.customcontrolclass_ascx 类型,但编译时没有错误。

Use

CustomControlClass c = (CustomControlClass)Ctrl.LoadControl("~/VirtualPathToASCX/CustomControlClass.ascx");

instead of

CustomControlClass c = new CustomControlClass();

UPDATE: fix cast bug

//LoadControl
ASP.customcontrolclass_ascx c = (ASP.customcontrolclass_ascx)this.LoadControl("~/Controls/CustomControlClass.ascx");
//set myValue
c.myValue = 3;

you can't see ASP.customcontrolclass_ascx type in VS AutoComplete List but it compiled with no error.

始于初秋 2024-10-23 12:43:23

不确定您的代码发生了什么,但使用大部分您展示的内容对我有用:

~/controls/testControl.ascx

<%@ Control Language='C#' AutoEventWireup='false' 
  Inherits='CustomControlClass' 
%>
<asp:Literal ID='litTest' runat='server'></asp:Literal>

.aspx页面:

<%@ Page Language='C#' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<script runat='server'>
protected override void OnInit(EventArgs e) {
  base.OnInit(e);
  MyClass.doWork(this.Page);
}
</script>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head runat='server'><title></title></head>
<body><form id='form1' runat='server'>
</form></body></html>

~/app_code/CustomControlClass.cs:

using System;
using System.Web;
using System.Web.UI.WebControls;

public partial class CustomControlClass : System.Web.UI.UserControl {
  private int _myValue= -1;
  public int myValue {
    get { return _myValue; }
    set { _myValue= value; }
  }
  private Literal _litTest;
  public Literal litTest {
    get { return _litTest; }
    set { _litTest= value; }

  }
  protected override void  OnInit(EventArgs e) {
    base.OnInit(e);
    litTest.Text = "TEST";
  }
}

~/app_code/MyClass:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public class MyClass {
  public static void doWork(Page Ctrl) {
    CustomControlClass c = 
      (CustomControlClass) Ctrl.LoadControl("~/controls/testControl.ascx");
    c.myValue = 1;
    Ctrl.Form.Controls.Add(c);

    Literal l = new Literal();
    l.Text = string.Format(
      "<p>CustomControlClass.myValue: {0} </p>", 
      c.myValue
    )
    + string.Format(
      "<p>CustomControlClass.litTest.Text: {0} </p>", 
      c.litTest.Text
    )
    ;
    Ctrl.Form.Controls.Add(l);
  }
}

换句话说,调用 LoadControl 时转换为 CustomControlClass () 对我有用。如果我理解正确的话那就是问题所在?

not sure what's going on with your code, but using mostly what you showed works for me:

~/controls/testControl.ascx:

<%@ Control Language='C#' AutoEventWireup='false' 
  Inherits='CustomControlClass' 
%>
<asp:Literal ID='litTest' runat='server'></asp:Literal>

.aspx page:

<%@ Page Language='C#' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<script runat='server'>
protected override void OnInit(EventArgs e) {
  base.OnInit(e);
  MyClass.doWork(this.Page);
}
</script>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head runat='server'><title></title></head>
<body><form id='form1' runat='server'>
</form></body></html>

~/app_code/CustomControlClass.cs:

using System;
using System.Web;
using System.Web.UI.WebControls;

public partial class CustomControlClass : System.Web.UI.UserControl {
  private int _myValue= -1;
  public int myValue {
    get { return _myValue; }
    set { _myValue= value; }
  }
  private Literal _litTest;
  public Literal litTest {
    get { return _litTest; }
    set { _litTest= value; }

  }
  protected override void  OnInit(EventArgs e) {
    base.OnInit(e);
    litTest.Text = "TEST";
  }
}

~/app_code/MyClass:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public class MyClass {
  public static void doWork(Page Ctrl) {
    CustomControlClass c = 
      (CustomControlClass) Ctrl.LoadControl("~/controls/testControl.ascx");
    c.myValue = 1;
    Ctrl.Form.Controls.Add(c);

    Literal l = new Literal();
    l.Text = string.Format(
      "<p>CustomControlClass.myValue: {0} </p>", 
      c.myValue
    )
    + string.Format(
      "<p>CustomControlClass.litTest.Text: {0} </p>", 
      c.litTest.Text
    )
    ;
    Ctrl.Form.Controls.Add(l);
  }
}

in other words the cast to CustomControlClass when calling LoadControl() works for me. if i understood you correctly that's the problem?

披肩女神 2024-10-23 12:43:23

LoadControl 的另一种工作方式(仅测试了 .NET 4)

页面中用法如下

protected void Page_Load(object sender, EventArgs e)
{
    Control ctrl = SomeClass.GetNewUserControl( "hello add me");

    Panel1.Controls.Add(ctrl);
}

在任何可以调用~/app_code/BaseMyControls.cs 的

using System;
using System.Collections.Generic;
using System.Web;

/// <summary>
/// Summary description for BaseMyControls
/// </summary>
public class BaseMyControls  : System.Web.UI.UserControl
{
    public string strProperty;

    public BaseMyControls()
    {

    }
}

~/app_code/SomeClassInApp_Code.cs:

using System;
using System.Collections.Generic;
using System.Web;

/// <summary>
/// Summary description for SomeClassInApp_Code
/// </summary>
public class SomeClassInApp_Code
{
    public static System.Web.UI.Control GetNewUserControl(string someString)
    {
        BaseMyControls bc = (BaseMyControls)(new System.Web.UI.UserControl()).LoadControl("~/controls/MyUC.ascx");
        bc.strProperty = someString;
        return bc;
    }
}

~/controls/MyUC.aspx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUC.ascx.cs" Inherits="MyUC" %>
<asp:Label runat="server" ID="lbl" /></asp:Label>

~/controls/MyUC.aspx.cs:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class MyUC : BaseMyControls
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string a = this.strProperty;

        lbl.Text = a;
    }
}

A different way of LoadControl which works (only .NET 4 tested)

Usage is as follows in any page you can call

protected void Page_Load(object sender, EventArgs e)
{
    Control ctrl = SomeClass.GetNewUserControl( "hello add me");

    Panel1.Controls.Add(ctrl);
}

~/app_code/BaseMyControls.cs:

using System;
using System.Collections.Generic;
using System.Web;

/// <summary>
/// Summary description for BaseMyControls
/// </summary>
public class BaseMyControls  : System.Web.UI.UserControl
{
    public string strProperty;

    public BaseMyControls()
    {

    }
}

~/app_code/SomeClassInApp_Code.cs:

using System;
using System.Collections.Generic;
using System.Web;

/// <summary>
/// Summary description for SomeClassInApp_Code
/// </summary>
public class SomeClassInApp_Code
{
    public static System.Web.UI.Control GetNewUserControl(string someString)
    {
        BaseMyControls bc = (BaseMyControls)(new System.Web.UI.UserControl()).LoadControl("~/controls/MyUC.ascx");
        bc.strProperty = someString;
        return bc;
    }
}

~/controls/MyUC.aspx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUC.ascx.cs" Inherits="MyUC" %>
<asp:Label runat="server" ID="lbl" /></asp:Label>

~/controls/MyUC.aspx.cs:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class MyUC : BaseMyControls
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string a = this.strProperty;

        lbl.Text = a;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文