【问题标题】:Content is not allowed between the opening and closing tags for user control用户控制的开始和结束标签之间不允许有内容
【发布时间】:2009-08-21 13:57:39
【问题描述】:

我想建立一个用户控件假设 MyDiv.ascx。 此控件呈现 div 标记,并在诸如添加少量属性等内容之后执行更多代码,这在此处无关紧要。 问题是我想要用户控件的开始标签和结束标签之间的文本。例如:

文本与其他一些 HTML 标记一起出现在此处。

所以当我做这样的事情时,我在运行网站时遇到了解析错误。 VS2008 还警告我说“元素的开始和结束标签之间不允许有内容 MyDiv”。

  • 问题 1:我可以做这样的事情,即打开之间的文本/标记 和用户控件的结束标签?

  • 问题 2:如果是,如何

【问题讨论】:

    标签: c# .net asp.net user-controls


    【解决方案1】:

    建议的解决方案对我不起作用。我找到了以下解决方案: 要么让你的用户控件继承自Panel 而不仅仅是UserControl,或者如果你有多个像我这样的内容,请将你的内容字段设置为PlaceHolders 而不是简单的Controls。

    添加了[PersistenceMode(PersistenceMode.InnerProperty)] 以避免XHTML 验证警告。

    public partial class DrawerControl : UserControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public PlaceHolder BodyContent { get; set; }
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public PlaceHolder GripContent { get; set; }
    
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            phBodyContent.Controls.Add(BodyContent);
            phGripContent.Controls.Add(GripContent);
        }
    }
    

    phBodyContentphGripContentPlaceHolders。

    这样我就可以将我的控件用于 ASPX 中的任何内容:

    <local:Drawer ID="ctlDrawer" runat="server">
        <BodyContent>
            <!--Insert any ASP content here-->
        </BodyContent>
        <GripContent>
            <!--Insert any ASP content here-->
        </GripContent>
    </local:Drawer>
    

    【讨论】:

    • 在您的情况下可能会选择复合控件(msdn.microsoft.com/en-us/library/…)一个很好的解决方案。你怎么说玛特?
    • 我在回答中添加了更多详细信息,以说明此解决方案的灵活性。当我必须将控件嵌入到带有资源的程序集中以便于分发时,我会切换到 CompositeControls。
    • 我在这里建议的一个补充是在将新的 PlaceHolder 对象添加到 phBodyContent 等之前对其进行空检查。当我指定一些 BodyContent 时它对我来说很好,但如果我这样做会出错不是。
    【解决方案2】:

    我相信您只需要对控件应用几个属性:

    [ParseChildren(false)]
    [PersistChildren(true)]
    public class MyDiv : UserControl
    {
        ...
    

    可能然后需要覆盖AddedControl - 我不确定。

    这样说 - 这就是我写过的唯一一个用户控件的工作原理:)

    【讨论】:

    • 哇......这就像一个魅力......但是......你能告诉我我怎样才能得到那个内部 html,因为我没有得到这种属性......就像 this.InnerHtml 或 this.Children..???
    • 您可以将 [ParseChildren(true, "Body")] 与字符串类型的名为“Body”的属性一起使用。这会将 InnerHtml 的内容放入您在 ParseChildren 注释中命名为第二个参数的任何属性中。
    【解决方案3】:

    我还想用“innerHtml”创建一个自定义控件。这就是我最终得到的结果(部分基于早期的一些答案/cmets)......

    div.ascx.cs:

    [ParseChildren(true, "Text")] //Store inner content in Text property
    public partial class div : System.Web.UI.UserControl
    {
        public string Text { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
            litText.Text = Text;  //Render it however you want
        }
    }
    

    div.ascx:

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="div.ascx.cs" Inherits="TestApp.Controls.div" %>
    <div>
        <asp:Literal ID="litText" runat="server" />
    </div>
    

    测试页面:

    <%@ register src="~/Controls/div.ascx" tagname="div" tagprefix="uc" %>
    <uc:div ID="div1" runat="server">Test data</uc:div>
    

    【讨论】:

      【解决方案4】:

      我发现了这个:

      ASP.Net: User control with content area, it's clearly possible but I need some details

      就像一个魅力,但我希望我可以抑制设计时消息,开始和结束标签之间不允许有内容,但它在运行时工作。

      [ParseChildren(true, "Content")]
      
      [PersistChildren(false)]
      
      public partial class CollapsiblePanelControl : UserControl
      
      {
      
          private Control content;
      
          // add the content
          this.MainContent.Controls.Add(content);
      
          // if this is not a post back
          if (!this.IsPostBack)
          {
              // set to true;
              this.Expanded = true;
          }
      }
      

      标记是这样的:

      <asp:Panel ID="CollapsiblePanelMainPanel" runat="server" CssClass="collapsiblepanel">
          <asp:Panel ID="CollapsibleHeaderPanel" runat="server" CssClass="collapsibleheaderpanel">
              <asp:ImageButton ID="CollapseButton" ImageUrl="~/Images/BlueArrowDown.png" runat="server" OnClick="ExpandButton_Click" CssClass="expandbutton" /> 
              <asp:Label ID="CollapsiblePanelHeaderLabel" runat="server" Text="Collapsed" CssClass="collapsiblelabel"></asp:Label>
          </asp:Panel>
          <asp:Panel ID="MainContent" runat="server">
          </asp:Panel>
      </asp:Panel>
      

      然后在客户端:

      <dc:CollapsiblePanelControl ID="CheckOnMePanel" runat="server" CssClass="checkonmepanel" EnableViewState="true"
              CollapsedHeight="20px" ExpandedHeight="300px" Expanded="true" HeaderText="Check On Me Email Service" >
          <Content>
              ...[Your Content Goes Here]
          </Content>
      </dc:CollapsiblePanelControl>
      

      【讨论】:

      • 您可以通过将此元数据添加到类中来抑制该错误消息:[ToolboxData("&lt;{0}:CONTROLNAME runat=server&gt; &lt;/{0}:CONTROLNAME&gt;")](注意打开和关闭标签之间的空格)
      【解决方案5】:

      向您的控件添加一个 Text 属性,并将此文本属性链接到在服务器上运行的标签,该标签将位于打开和关闭 div 之间。

      【讨论】:

        【解决方案6】:

        您可能要小心,如果您在内容区域中放置服务器控件会怎样...

        您可能只想让控件从面板继承并覆盖您需要调整的任何方法?可能更容易或更难,具体取决于您需要自定义的内容

        public class MyDiv : Panel
        {
        
        }
        

        【讨论】:

        • 我想我不能这样做...因为它已经从 UserControl 类继承...所以将无法从其他类继承...它们是我可以实现的任何接口???
        • 面板本身继承自 UserControl,因此您仍然可以使用所有 UserControl 的东西。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-04
        • 1970-01-01
        • 2011-06-07
        • 2016-02-12
        相关资源
        最近更新 更多