2

テンプレートのようなユーザーコントロールを開発する必要があります。これは、他のコントロールを含む任意のコンテンツを受け入れます。

WmlCard.ascx

<asp:PlaceHolder ID="phContent" runat="server">
<card id="<%= Me.CardId %>" title="<%= Me.Title %>"> 
<p>
    <%= Me.InnerText %>
</p>
</card>
</asp:PlaceHolder>

これは次のように使用されます:
ListaTelefonica.aspx

<%@ Register TagPrefix="sic" TagName="Card" Src="~/path/to/WmlCard.ascx"%>    
<sic:Card ID="BuscaCard" runat="server" CardId="busca" title="Lista Telefônica" Visible="false">
   <asp:Literal ID="SomeLiteral" runat="server" Visible="false">Some text<br /></asp:Literal>
   <asp:Literal ID="RuntimeFilledLiteral" runat="server" Visible="false" /><br /></asp:Literal>
   Any text.
</sic:Card>

Ascxユーザーコントロールがを継承する必要があるのは残念ですSystem.Web.UI.UserControl。たとえば、私が継承できればSystem.Web.UI.WebControls.WebControl、それはケーキになります。

私の問題はこれに似いますが、テキストだけでなく、コントロールはその中の他のコントロールを受け入れる必要があります。


<ParseChildren(False)>でオーバーライドAddParsedSubObject(Object)してみましWmlCardたが、ページの読み込み前にhtmlがレンダリングされるため、解決策にはなりませんRuntimeFilledLiteral.Text。たとえば、ページのPage_Loadの値を変更しても意味がありません。

私が得た最初のエラー:
パーサーエラーメッセージ:タイプ'ASP.sic_sicphone_usercontrol_wmlcard_ascx'には'Literal'という名前のパブリックプロパティがありません。

追加後<PersistenceMode(PersistenceMode.InnerDefaultProperty), ParseChildren(True, "InnerText")>
「sic:Card」の「InnerText」プロパティは子オブジェクトを許可しません。

上記と同じですが、WmlCardのプロパティInnerTextタイプをからStringに変更しますList(Of Object)
リテラルコンテンツ(「任意のテキスト」)は、「System.Collections.IList」内では許可されていません。

追加<ParseChildren(False)>してオーバーライドした後AddParsedSubObject
エラーメッセージは表示されませんが、内部コントロールのランタイムプロパティを変更する前に、WmlCardのコンテンツがhtmlにレンダリングされます。

WmlCardを次のSystem.Web.UI.WebControls.PlaceHolder代わりに継承するように変更した場合System.Web.UI.UserControl
'... UserControl.WmlCard'は、クラス'System.Web.UI.UserControl'を拡張しないため、ここでは許可されません。

4

4 に答える 4

3

有効な方法を見つけました:

1)私のコントロール(WmlCard.ascx)の中に何も入れません。

2)<ParseChildren(False)>WmlCardに属性を追加しました。

3)WmlCardのイベントPreRenderにハンドラーを追加しました。

Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
  Dim litBefore As New Literal()
  litBefore.Text = String.Format("<card id=""{0}"" title=""{1}""><p>", Me.CardId, Me.Title)

  Dim litAfter As New Literal()
  litAfter.Text = "</p></card>"

  Me.Controls.AddAt(0, litBefore)
  Me.Controls.Add(litAfter)
End Sub

以上です。すべてが機能しています。これを通して考えてくれてありがとう!

于 2011-03-03T16:56:44.960 に答える
0

必要なのは、テンプレート化されたユーザーコントロールです。

詳細なハウツーについては、この記事を参照してください:http: //msdn.microsoft.com/en-us/library/36574bf6.aspx

于 2011-03-03T16:39:43.753 に答える
0

実際には、カスタムユーザーコントロールを作成し、プレースホルダーから継承することができ、問題を解決する必要がありますか?

提案されているようにテンプレート化された制御方法を使用できますが、それを実行する理由がわかりません。

 [SupportsEventValidation, DefaultEvent("YourEventName")]
    [ParseChildren(true)]
    [PersistChildren(false)]
    [ToolboxBitmap(typeof(System.Web.UI.WebControls.Panel))]
    public class MyCustomControl : System.Web.UI.WebControls.PlaceHolder, INamingContainer, IPostBackDataHandler, IPostBackEventHandler

Renderメソッドをオーバーライドして、レンダリングされたHTMLを制御できます。私はあなたの実際の問題を見るのに苦労しています。

于 2011-03-03T16:43:29.033 に答える
0

これは簡単に機能します。

[ParseChildren(false)]
public class CssControl : System.Web.UI.UserControl
{
    protected override void Render(HtmlTextWriter writer)
    {
        string html = null;
        using(var innerWriter = new System.IO.StringWriter())
        using(var htmlWriter = new HtmlTextWriter(innerWriter))
        {
            base.Render(htmlWriter);
            html = innerWriter.GetStringBuilder().ToString();               
        }

        var min = ScriptAndCssParser.MinifyCssFromHtml(html);
        writer.Write(min);
    }
}

私の場合、私の目標は、マスターページレベルのコントロールに子HTMLと、asp:contentブロックなどのサーバーコントロールを含めることでした。そうすれば、Viewpagesはスタイルシートをチェーンの上位にあるマスターページに渡すことができます。

次に、生成されたすべてのHTMLをインターセプトし、CSSファイルを縮小したいと思いました。縮小部分はこの質問の範囲外ですが、上記ParseChildren(false)は.aspxの「要素を含めることができません...」エラーを防ぎます。次にbase.Render()、内部ライターを呼び出すと、既存のWebフォームパイプラインを使用して実行できます。サーバーコントロールとプレーンHTMLコンテンツの両方のすべてのレンダリング。

于 2019-10-18T17:39:54.447 に答える