gpt4 book ai didi

c# - 为什么我的自定义用户控件的子控件没有被初始化?

转载 作者:太空狗 更新时间:2023-10-29 23:35:48 25 4
gpt4 key购买 nike

更新: 我一直在试验我的控件,我想我已经接近了。请继续阅读以获取最新信息。

我有 2 个 ASP.NET 2.0 用户控件,其中一个位于另一个的内部。在内部控件中,我有一个 HtmlAnchor 标记控件,我试图从外部控件为其设置 URL。当我尝试从呈现页面的标记设置 HRef 属性时,HtmlAnchor 控件为 null 并引发异常。

URL set 属性在内部或外部控件的 OnInit 事件之前以及主页的“OnPreInit”之前被调用' 事件。我假设这是因为我在页面上的父控件标记中设置子控件的 URL 我正在呈现控件,这意味着值设置在 OnInit() 之前.这是我正在使用的代码的(精简)版本:

[ParseChildren(true)]// <- Setting this to false makes the 
// page render without an exception
// but ignores anything in the markup.
[PersistChildren(false)]
public partial class OuterControl : System.Web.UI.UserControl
{
// The private '_Inner' control is declared
// in the .ascx markup of the control
[PersistenceMode(PersistenceMode.InnerProperty)]
public InnerControl Inner
{
get{ return _Inner; }
set{ _Inner = value; }
}
}

public partial class InnerControl : System.Web.UI.UserControl
{
// The private 'linkHref' control is declared
// in the .ascx markup of the control
public string Url
{
get { return linkHref.HRef; }
set { linkHref.HRef = value; }
}
}

在我的 Default.aspx 页面上使用 OuterControl 是这样的:

<uc1:OuterControl ID="OuterCtrl1" runat="server">
<Inner Url="#" />
</uc1:OuterControl>

在上面的标记示例中,如果我尝试呈现此页面,则会抛出异常,因为 linkHref 控件为空。使用我的调试器,我可以看到 InnerControl 中的每个控件都是空的,但是当访问 Url 属性时,InnerControl 和 OuterControl 的 OnInit() 事件都没有被触发.

更新
我认为添加属性“ParseChildren”和“PersistChildren”会有所帮助。我以前在服务器控件中使用过它们,但从未在用户控件中使用过它们,尽管效果似乎相似。我认为我没有正确解释这两个属性的文档,但它可以阻止抛出异常。但是,页面标记将被忽略。

有没有人知道有什么方法可以让这个工作。我不明白为什么这些控件会在 OnInit() 之前设置值。当我尝试使用 ASPX 标记设置它们的值时,InnerControl 的构造函数被调用了两次。一次是根据标记设置值(我假设),然后再次在 OnInit() 上设置值(我猜这就是标记值被忽略的原因)。

这种努力是无望的还是我只是从错误的角度接近它?

最佳答案

问候丹,

我之前遇到过类似的嵌套控件困惑问题,所以我发现自己很想帮忙,我也把它标记为最喜欢的,因为我喜欢它。

我将问题重现如下:-

创建了一个名为 Inner 的用户控件:

内部.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Inner.ascx.cs" Inherits="Inner" %>
<a runat="server" id="linkHref">I'm inner</a>

内部.ascx.cs

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

public partial class Inner : System.Web.UI.UserControl
{
public string Url
{
get
{
return this.linkHref.HRef;
}
set
{
this.linkHref.HRef = value;
}
}
}

创建了一个名为 Outer 的用户控件:

外层.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Outer.ascx.cs" Inherits="Outer" %>
<%@ Register src="Inner.ascx" tagname="Inner" tagprefix="uc1" %>
<uc1:Inner ID="_Inner" runat="server" />

外层.ascx.cs

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

public partial class Outer : System.Web.UI.UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
public Inner Inner
{
get
{
return this._Inner;
}
}
}

然后创建了一个名为 Default 的页面:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register src="Outer.ascx" tagname="Outer" tagprefix="uc1" %>
<%@ Reference Control="~/Inner.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:Outer ID="Outer1" runat="server">
<Inner Url="http://google.com" />
</uc1:Outer>
</div>
</form>
</body>
</html>

有了所有这些,页面“默认”运行良好。

我在你的代码中发现奇怪的是这一行:

public InnerControl Inner
{
//...
set{ _Inner = value; }
}

为内部控件创建一个 setter 有什么意义?我无法理解。内部控件实例应该是从外部控件中的标记创建的,并且正是这个创建的实例应该操作其 html anchor 。如果我将这些行添加到 Outer.ascx.cs 中的 Inner 属性

set
{
this._Inner = (ASP.inner_ascx)value;
}

我将得到与原始情况相同的空引用异常。我认为 setter 指示 ASP.Net 页面生成器创建另一个内部控件实例并使用 Inner 属性设置它。我不确定,但如果您有时间,您可以通过检查页面构建器生成的 cs 文件来确切了解这是如何发生的,它们驻留在临时 ASP.Net 文件中。

关于c# - 为什么我的自定义用户控件的子控件没有被初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/429202/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com