阿罗哈,
我有一个自定义控件,我需要在类中实例化并添加到页面中。我的类有一个函数,我传递Page
,所以我可以访问页面上的控件。我已经使用这种方法添加标准的ASP控件以及它按预期工作的一切。我的问题是自定义控件的类型是否已知定义?
我阅读here将.cs从控件移动到App_Code文件夹中,但是当我这样做时,它不会编译,因为它没有看到ascx中的控件有效。例如,我得到CS0103: The name 'litTest' does not exist in the current context
。因为它们是部分类,我在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这个词显示得很好。我尝试从MyClass.doWork()
,Load
和Init
个回调中调用PreInit
,这些都会导致这一点。
更新
由于 Minh Nguyen 建议我可以使用Ctrl.LoadControl("~/Controls/CustomControlClass.ascx");
来加载控件但我不能将其作为自己的类型转换我必须将其指定为Control类型:
Control c= Ctrl.LoadControl("~/Controls/CustomControlClass.ascx");
执行此操作将允许我将控件添加到页面并使其按预期工作。缺点是我无法访问任何控件属性。为了解决这个问题,我这样做:
c.GetType().GetProperty("myValue").SetValue(c, 1, null);
这样可行,但我不确定它的使用价格有多贵。我希望我能投出控件,但是当我尝试时会出错。
我暂时没有回复,看看是否还有其他选择。
答案 0 :(得分:4)
使用
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自动完成列表中看到ASP.customcontrolclass_ascx类型,但它编译时没有错误。
答案 1 :(得分:1)
不确定您的代码会发生什么,但使用主要是您展示的内容对我有用:
<强>〜/控制/ 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 。如果我理解你是正确的问题吗?
答案 2 :(得分:1)
一种不同的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;
}
}
<强>〜/控制/ MyUC.aspx:强>
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUC.ascx.cs" Inherits="MyUC" %>
<asp:Label runat="server" ID="lbl" /></asp:Label>
<强>〜/控制/ 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;
}
}