2010-11-05 18 views
8

Tôi đang tạo một điều khiển người dùng mà tôi muốn có các thuộc tính bên trong cũng như các thuộc tính thông thường. Mặc dù chức năng thực tế của điều khiển không có gì để làm với, nói, UpdatePanel, tôi đang cố gắng để tạo ra một cái gì đó với đánh dấu tương tự ASPX. Các nhà phát triển thiết kế trang nên có thể sử dụng kiểm soát của tôi như:Làm thế nào để tạo điều khiển người dùng ASP.NET với các thuộc tính bên trong được sử dụng với đánh dấu tương tự như UpdatePanel?

<ns:MyControl ID="someID" runat="server" SomeOtherAttribute="true"> 
    <ContentTemplate> 
    <asp:Label ID="someLabel" runat="server" Text="Normal page markup and controls should go here" /><br /> 
    <p>This should be OK too.</p> 
    </ContentTemplate> 
    <ControlEvent ControlName="idOfOtherControl" Event="Click" /> 
    <ControlEvent ControlName="idOfSomeOtherControl" Event="MouseOver" /> 
</ns:MyControl> 

Cũng chấp nhận được sẽ được gói các ControlEvent thẻ trong một số thẻ khác, giống như những gì xảy ra khi sử dụng UpdatePanel:

<ns:MyControl ID="someID" runat="server" SomeOtherAttribute="true"> 
    <ContentTemplate> 
    <asp:Label ID="someLabel" runat="server" Text="Normal page markup and controls should go here" /><br /> 
    <p>This should be OK too.</p> 
    </ContentTemplate> 
    <ControlEvents> 
    <ns:ControlEvent ControlName="idOfOtherControl" Event="Click" /> 
    <ns:ControlEvent ControlName="idOfSomeOtherControl" Event="MouseOver" /> 
    </ControlEvents> 
</ns:MyControl> 

Nhưng , thẻ ControlEvents chỉ nên cho phép một thẻ cụ thể này, không cho phép đánh dấu máy chủ thông thường hoặc bất kỳ thứ gì.

Tôi hiểu cách tải nội dung bên trong ContentTemplate để hiển thị (trong số Page_Init, tôi sử dụng phương thức ITemplate.InstantiateIn(placeholderControl)). Phần đó hoạt động tốt. Trường hợp tôi gặp sự cố là nhận phần ControlEvent hoạt động. Tôi có thể tạo ra các tài sản bên trong code-behind thích:

[TemplateInstance(TemplateInstance.Multiple)] 
[PersistenceMode(PersistenceMode.InnerProperty)] 
[TemplateContainer(typeof(ControlEvent))] 
public List<ControlEvent> ControlEvents { get; set; } 

Bằng cách đó, ASP.NET dường như hiểu rằng tôi muốn có một thẻ ControlEvents. Nhưng, tôi không thể nhận được các thuộc tính, hoặc là thuộc tính bên trong hoặc các thuộc tính, để được nhận ra. Thay vào đó, nếu tôi thử loại đánh dấu đầu tiên, tôi nhận được một lỗi trình phân tích cú pháp thời gian chạy: "Thuộc tính ControlEvents 'không có thuộc tính có tên' ControlName '." Nếu tôi thử loại đánh dấu thứ hai, tôi nhận được lỗi NullReferenceException làm lỗi phân tích cú pháp khi chạy, với lỗi được tạo tại dòng <ns:ControlEvent>.

Tôi đã kiểm tra trực tuyến nhưng tôi chưa tìm thấy ví dụ hay giải thích tốt về cách thực hiện những gì tôi đang cố gắng thực hiện với ControlEvent hoặc ControlEvents. Tôi đang thiếu gì? Ai đó có thể chỉ cho tôi một ví dụ tốt ở đây?

Cảm ơn!

Edit:

Hóa ra là một số trong những vấn đề là do làm thế nào tôi có sự kiểm soát đăng ký vào trang sử dụng nó. Nếu tôi đang sử dụng:

<%@ Register Src="~/Controls/MyControl.ascx" TagPrefix="ns" TagName="MyControl" %> 

Dường như bản thân kiểm soát đã được nhận dạng trong đánh dấu, nhưng ns:ControlEvent thì không. Nếu tôi thay đổi Register tới:

<%@ Register Namespace="Namespace.Controls" TagPrefix="ns" Assembly="MyAssembly" %> 

nó làm việc như xa như tìm hiểu sự kiểm soát bản thân (với điều kiện là runat="server" đã được đưa vào ns:ControlEvent thẻ). Tuy nhiên, các điều khiển con của MyControl không được khởi tạo hoặc hiển thị nữa và các sự kiện của điều khiển như Page_InitPage_Load không kích hoạt.

Sau nhiều lần lộn xộn, tôi đã tìm ra rằng dường như tôi cần cả hai chỉ thị Register. Điều này có vẻ giống như một giải pháp "lộn xộn", và nó thậm chí không thực sự giải quyết mọi thứ, vì (không phải) ít nhất một số đánh dấu trong kiểm soát của tôi không hiển thị, mặc dù điều khiển mẫu (ContentTemplate) dường như đang hoạt động trở lại.

Tôi có thể thiếu những thứ gì ở đây để điều khiển này ít lộn xộn hơn và điều đó có thể khiến cho điều khiển này thực sự hiển thị mọi thứ chính xác?

+0

Bạn có thể đăng ký các điều khiển trong 'Web.config' để chúng áp dụng chung cho tất cả các trang trong ứng dụng của bạn, thay vì phải đưa chúng vào mọi trang. – batwad

+0

@batwad Đúng, và tôi sẽ phải thử. Tôi đã hy vọng không phải làm điều đó mặc dù, chủ yếu là do các tiêu chuẩn và quy ước về mã tổ chức. Bên cạnh đó, tôi biết rằng UpdatePanel và tương tự là "được xây dựng trong", nhưng đối với điều khiển mẫu người dùng, là phải bao gồm trong Web.config hoặc hai lần trong trang thực sự là tiêu chuẩn trong ASP.NET 3.5? – Andrew

Trả lời

10

Thuộc tính phải được gọi là Collection chứ không phải là List; ngoài điều đó, điều quan trọng nhất cần nhớ ở đây là điều khiển chính phải có thuộc tính [ParseChildren(true)] được thiết lập để hoạt động, nếu không bộ sưu tập sẽ là null.

Sau đây (máy chủ điều khiển) mẫu hoạt động như mong đợi:

public class ControlEvent 
    { 
     public string ControlName { get; set; } 
     public string Event { get; set; } 
    } 

    [ParseChildren(true)] 
    public class SampleControl : System.Web.UI.Control, INamingContainer 
    { 
     [PersistenceMode(PersistenceMode.InnerProperty)] 
     [TemplateContainer(typeof(SampleControl))] 
     public ITemplate ContentTemplate { get; set; } 

     [MergableProperty(false), PersistenceMode(PersistenceMode.InnerProperty), DefaultValue((string)null)] 
     public Collection<ControlEvent> ControlEvents { get; set; } 

     protected override void CreateChildControls() 
     { 
      base.CreateChildControls(); 

      if (ContentTemplate != null) 
       ContentTemplate.InstantiateIn(this); 

      if (null != ControlEvents) 
       foreach (ControlEvent e in ControlEvents) 
        Controls.Add(new Label() { Text = string.Format("ControlName:{0}, Event:{1}", e.ControlName, e.Event) }); 
     } 
    } 

HTH.

+0

Điều này chỉ cho tôi đi đúng hướng. Cảm ơn! Tôi đã có ParseChildren (đúng). Tôi thấy rằng vấn đề đã kết thúc bằng cách tôi đã kiểm soát được đăng ký trong trang. Xem chỉnh sửa cho câu hỏi của tôi (sắp có). – Andrew

Các vấn đề liên quan