سؤال

لقد بدأت للتو في استخدام عناصر تحكم المستخدم المخصصة في C# وأتساءل عما إذا كان هناك أي أمثلة حول كيفية كتابة واحدة تقبل العلامات المتداخلة؟

على سبيل المثال، عندما تقوم بإنشاء asp:repeater يمكنك إضافة علامة متداخلة لـ itemtemplate.

هل كانت مفيدة؟

المحلول

كتبت أ مشاركة مدونة حول هذا منذ بعض الوقت.باختصار، إذا كان لديك عنصر تحكم بالعلامة التالية:

<Abc:CustomControlUno runat="server" ID="Control1">
    <Children>
        <Abc:Control1Child IntegerProperty="1" />
    </Children>
</Abc:CustomControlUno>

ستحتاج إلى أن يكون الكود الموجود في عنصر التحكم على غرار ما يلي:

[ParseChildren(true)]
[PersistChildren(true)]
[ToolboxData("<{0}:CustomControlUno runat=server></{0}:CustomControlUno>")]
public class CustomControlUno : WebControl, INamingContainer
{
    private Control1ChildrenCollection _children;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Control1ChildrenCollection Children
    {
        get
        {
            if (_children == null)
            {
                _children = new Control1ChildrenCollection();
            }
            return _children;
        }
    }
}

public class Control1ChildrenCollection : List<Control1Child>
{
}

public class Control1Child
{
    public int IntegerProperty { get; set; }
}

نصائح أخرى

لقد تابعت منشور مدونة Rob، وقمت بإجراء تحكم مختلف قليلاً.عنصر التحكم شرطي، تمامًا مثل جملة if:

<wc:PriceInfo runat="server" ID="PriceInfo">
    <IfDiscount>
        You don't have a discount.
    </IfDiscount>
    <IfNotDiscount>
        Lucky you, <b>you have a discount!</b>
    </IfNotDiscount>
</wc:PriceInfo>

في الكود قمت بعد ذلك بتعيين HasDiscount خاصية التحكم إلى قيمة منطقية، والتي تقرر البند الذي سيتم تقديمه.

يتمثل الاختلاف الكبير عن حل Rob في أن البنود الموجودة في عنصر التحكم يمكنها حقًا الاحتفاظ برمز HTML/ASPX التعسفي.

وهنا هو رمز التحكم:

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

namespace WebUtilities
{
    [ToolboxData("<{0}:PriceInfo runat=server></{0}:PriceInfo>")]
    public class PriceInfo : WebControl, INamingContainer
    {
        private readonly Control ifDiscountControl = new Control();
        private readonly Control ifNotDiscountControl = new Control();

        public bool HasDiscount { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Control IfDiscount
        {
            get { return ifDiscountControl; }
        }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Control IfNotDiscount
        {
            get { return ifNotDiscountControl; }
        }

        public override void RenderControl(HtmlTextWriter writer)
        {
            if (HasDiscount)
                ifDiscountControl.RenderControl(writer);
            else
                ifNotDiscountControl.RenderControl(writer);
        }
    }
}

انتهى بي الأمر بشيء مشابه جدًا للإجابة روب (في أرشيف الطريق) @gudmundur-h, ، لكنني استخدمت ITemplate للتخلص من ذلك المزعج "لا يمكنك وضع المحتوى بين علامات X" أثناء الاستخدام.لست متأكدًا تمامًا مما هو مطلوب بالفعل أم لا، لذلك كل شيء هنا في حالة حدوث ذلك.

ترميز التحكم الجزئي/المستخدم: mycontrol.ascx

لاحظ القطع المهمة: plcChild1 و plcChild2.

<!-- markup, controls, etc -->
<div class="shell">
    <!-- etc -->

    <!-- optional content with default, will map to `ChildContentOne` -->
    <asp:PlaceHolder ID="plcChild1" runat="server">
        Some default content in the first child.
        Will show this unless overwritten.
        Include HTML, controls, whatever.
    </asp:PlaceHolder>

    <!-- etc -->

    <!-- optional content, no default, will map to `ChildContentTwo` -->
    <asp:PlaceHolder ID="plcChild2" runat="server"></asp:PlaceHolder>

</div>

رمز التحكم الجزئي/المستخدم الموجود خلف: mycontrol.ascx.cs

[ParseChildren(true), PersistChildren(true)]
[ToolboxData(false /* don't care about drag-n-drop */)]
public partial class MyControlWithNestedContent: System.Web.UI.UserControl, INamingContainer {
    // expose properties as attributes, etc

    /// <summary>
    /// "attach" template to child controls
    /// </summary>
    /// <param name="template">the exposed markup "property"</param>
    /// <param name="control">the actual rendered control</param>
    protected virtual void attachContent(ITemplate template, Control control) {
        if(null != template) template.InstantiateIn(control);
    }

    [PersistenceMode(PersistenceMode.InnerProperty),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public virtual ITemplate ChildContentOne { get; set; }

    [PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public virtual ITemplate ChildContentTwo { get; set; }

    protected override void CreateChildControls() {
        // clear stuff, other setup, etc
        // needed?
        base.CreateChildControls();

        this.EnsureChildControls(); // cuz...we want them?

        // using the templates, set up the appropriate child controls
        attachContent(this.ChildContentOne, this.plcChild1);
        attachContent(this.ChildContentTwo, this.plcChild2);
    }
}

نقاط مهمة (؟):

  • ParseChildren -- هكذا الاشياء يظهر?
  • PersistChildren - بحيث لا تتم إعادة تعيين الأشياء التي تم إنشاؤها ديناميكيًا؟
  • PersistenceMode(PersistenceMode.InnerProperty) - هكذا تكون الضوابط تحليلها بشكل صحيح
  • DesignerSerializationVisibility(DesignerSerializationVisibility.Content) -- نفس الشيء؟

استخدام التحكم

<%@ Register Src="~/App_Controls/MyStuff/mycontrol.ascx" TagPrefix="me" TagName="MyNestedControl" %>

<me:MyNestedControl SomeProperty="foo" SomethingElse="bar" runat="server" ID="meWhatever">
    <%-- omit `ChildContentOne` to use default --%>
    <ChildContentTwo>Stuff at the bottom! (not empty anymore)</ChildContentTwo>
</me:MyNestedControl>

تخميني هو أنك تبحث عن شيء من هذا القبيل؟ http://msdn.microsoft.com/en-us/library/aa478964.aspx

تمت إزالة علاماتك أو أنها غير مرئية، لذا لا يمكنني مساعدتك حقًا في هذا الأمر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top