2008-11-20 53 views
13

Tôi đã cố tạo một điều khiển tùy chỉnh hoạt động chính xác như điều khiển Bảng điều khiển ngoại trừ được bao quanh bởi một vài div và như vậy để tạo giao diện hộp tròn. Tôi đã không thể tìm thấy một ví dụ tốt về cách làm điều này.Kiểm soát vùng chứa ASP.NET tùy chỉnh

Tôi cần có thể đặt văn bản và điều khiển bên trong bộ điều khiển và truy cập trực tiếp mà không cần tham khảo bảng điều khiển (chính xác cách hoạt động của công cụ điều khiển Bảng điều khiển).

Có ai có bất kỳ ví dụ nào về điều này không?

Trả lời

15

Có hai cách để thực hiện việc này. Một là triển khai INamingContainer trên sự kiểm soát của bạn và phải mất rất nhiều công sức.

Cách khác là kế thừa từ Bảng điều khiển và ghi đè phương thức RenderBeginTag và RenderEndTag để thêm đánh dấu tùy chỉnh của bạn. Điều này thật dễ dàng.

public class RoundedCornersPanel : System.Web.UI.WebControls.Panel 
{ 
    public override RenderBeginTag (HtmlTextWriter writer) 
    { 
     writer.Write("Your rounded corner opening markup"); 
     base.RenderBeginTag(writer); 
    } 

    public override RenderEndTag (HtmlTextWriter writer) 
    { 
     base.RenderEndTag(writer); 
     writer.Write("Your rounded corner closing markup");      
    } 
} 
+0

Đây có lẽ là một câu hỏi rất ngu ngốc nhưng vì tôi không thể đặt mã này trong điều khiển người dùng thông thường (.ascx), tôi sẽ đặt nó ở đâu? Tôi tạo ra một lớp và đặt nó trong đó, nhưng sau đó tôi không biết làm thế nào để thêm nó vào một trang (kéo chỉ cần tạo ra một liên kết) –

+0

Đăng một câu hỏi về cách sử dụng ASP.NET Server điều khiển, và tôi có thể trả lời, Tôi không phù hợp với lời giải thích trong hộp bình luận nhỏ này. – FlySwat

+0

Nếu bạn xây dựng mã, mã sẽ xuất hiện trên hộp công cụ. –

3

Tạo lớp thừa hưởng System.Web.UI.Control và ghi đè phương pháp Render (HtmlTextWriter). Trong phương pháp này, hiển thị các thẻ bắt đầu xung quanh, sau đó hiển thị con (RenderChildren), sau đó kết xuất thẻ kết thúc.

protected override void Render (HtmlTextWriter output) 
{ 
    output.Write ("<div>"); 
    RenderChildren (output); 
    output.Write ("</div>"); 
} 

Góc tròn thường đạt được bằng cách sử dụng CSS và hình ảnh góc cho góc trên cùng bên trái, trên cùng bên phải, dưới cùng bên trái và dưới cùng bên phải. Nó có thể được thực hiện bằng cách sử dụng 4 div lồng nhau, hoạt động như các lớp, mỗi lớp có một hình ảnh góc làm hình nền của chúng.

-1
public class myCustomPanel : Panel 
{ 
    public override void RenderBeginTag(HtmlTextWriter writer) 
    { 
     writer.AddAttribute(HtmlTextWriterAttribute.Class, "top_left_corner"); 
     writer.RenderBeginTag(HtmlTextWriterTag.Div); 
      base.RenderBeginTag(writer); 
    } 

    public override void RenderEndTag(HtmlTextWriter writer) 
    { 
      base.RenderEndTag(writer); 
     writer.RenderEndTag(); 
    } 

} 
0

Chỉ cần một điều bạn có thể sử dụng, có một rounded corner extender trong bộ công cụ ajax ASP.Net.

Tôi biết nó không chính xác những gì bạn yêu cầu, nhưng bạn không phải viết bất kỳ mã tùy chỉnh nào.

Hy vọng điều đó sẽ hữu ích!

13

Hiện đã có một vài câu trả lời ở đây, nhưng tôi chỉ muốn dán triển khai cơ bản nhất của điều này mà không kế thừa từ lớp Bảng điều khiển. Vì vậy, ở đây nó đi:

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

[ToolboxData("<{0}:SimpleContainer runat=server></{0}:SimpleContainer>")] 
[ParseChildren(true, "Content")] 
public class SimpleContainer : WebControl, INamingContainer 
{ 
    [PersistenceMode(PersistenceMode.InnerProperty)] 
    [TemplateContainer(typeof(SimpleContainer))] 
    [TemplateInstance(TemplateInstance.Single)] 
    public virtual ITemplate Content { get; set; } 

    public override void RenderBeginTag(HtmlTextWriter writer) 
    { 
     // Do not render anything. 
    } 

    public override void RenderEndTag(HtmlTextWriter writer) 
    { 
     // Do not render anything. 
    } 

    protected override void RenderContents(HtmlTextWriter output) 
    { 
     output.Write("<div class='container'>"); 
     this.RenderChildren(output); 
     output.Write("</div>"); 
    } 

    protected override void OnInit(System.EventArgs e) 
    { 
     base.OnInit(e); 

     // Initialize all child controls. 
     this.CreateChildControls(); 
     this.ChildControlsCreated = true; 
    } 

    protected override void CreateChildControls() 
    { 
     // Remove any controls 
     this.Controls.Clear(); 

     // Add all content to a container. 
     var container = new Control(); 
     this.Content.InstantiateIn(container); 

     // Add container to the control collection. 
     this.Controls.Add(container); 
    } 
} 

Sau đó, bạn có thể sử dụng nó như thế này:

<MyControls:SimpleContainer 
    ID="container1" 
    runat="server"> 
    <Content> 
     <asp:TextBox 
      ID="txtName" 
      runat="server" /> 

     <asp:Button 
      ID="btnSubmit" 
      runat="server" 
      Text="Submit" /> 
    </Content> 
</MyControls:SimpleContainer> 

Và từ codebehind bạn có thể làm những việc như thế này:

this.btnSubmit.Text = "Click me!"; 
this.txtName.Text = "Jack Sparrow"; 
+0

Ví dụ tốt. Làm việc cho tôi. –

+0

Cảm ơn. Đã làm cho tôi. –

+0

Bạn sẽ thay đổi lớp SimpleContainer như thế nào nếu mục tiêu là có nội dung bên trái và nội dung phù hợp? Bạn có thể chỉ có 2 thuộc tính ITemplate không? Còn thuộc tính ParseChildren thì sao? – SynBiotik

0

Tôi nhìn câu hỏi này bởi vì Tôi muốn tạo ra một bảng bố trí 2 cột. (Không hoàn toàn nhưng một ví dụ đơn giản hơn nhiều của những gì tôi cần tôi chia sẻ những giải pháp mà tôi vết thương bằng cách sử dụng:.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace Syn.Test 
{ 
    [DefaultProperty("Text")] 
    [ToolboxData("<{0}:MultiPanel runat=server></{0}:MultiPanel>")] 
    [ParseChildren(true)] 
    [PersistChildren(false)] 
    public class MultiPanel : WebControl, INamingContainer 
    { 
     public ContentContainer LeftContent { get; set; } 

     public ContentContainer RightContent { get; set; } 

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

     protected override void Render(HtmlTextWriter output) 
     { 
      output.AddStyleAttribute("width", "600px"); 
      output.RenderBeginTag(HtmlTextWriterTag.Div); 

      output.AddStyleAttribute("float", "left"); 
      output.AddStyleAttribute("width", "280px"); 
      output.AddStyleAttribute("padding", "10px"); 
      output.RenderBeginTag(HtmlTextWriterTag.Div); 
      LeftContent.RenderControl(output); 
      output.RenderEndTag(); 

      output.AddStyleAttribute("float", "left"); 
      output.AddStyleAttribute("width", "280px"); 
      output.AddStyleAttribute("padding", "10px"); 
      output.RenderBeginTag(HtmlTextWriterTag.Div); 
      RightContent.RenderControl(output); 
      output.RenderEndTag(); 

      output.RenderEndTag(); 
     } 
    } 

    [ParseChildren(false)] 
    public class ContentContainer : Control, INamingContainer 
    { 
    } 
} 

Vấn đề tôi vẫn có được IntelliSense does't làm việc cho trong kịch bản này, nó sẽ không gợi ý các thẻ Nội dung bên trái và bên phải.

2

Nếu bạn không muốn kế thừa trực tiếp từ WebControl thay vì từ Bảng điều khiển, cách dễ nhất để làm điều này là trang trí lớp học với thuộc tính [ParseChildren(false)]. Mặc dù ngay từ cái nhìn đầu tiên, điều này có thể gợi ý rằng bạn không muốn phân tích trẻ em, những gì mà false thực sự chỉ ra là bạn không muốn trẻ em được coi là tài sản. Thay vào đó, bạn muốn chúng được coi là điều khiển.

Bằng cách sử dụng thuộc tính này, bạn nhận được hầu như tất cả các chức năng out of the box:

[ToolboxData("<{0}:RoundedBox runat=server></{0}:RoundedBox>")] 
[ParseChildren(false)] 
public class RoundedBox : WebControl, INamingContainer 
{ 
    public override void RenderBeginTag(HtmlTextWriter writer) 
    { 
     writer.Write("<div class='roundedbox'>"); 
    } 

    public override void RenderEndTag(HtmlTextWriter writer) 
    { 
     writer.Write("</div>"); 
    } 
} 

Điều này sẽ cho phép bạn thêm RoundedBox điều khiển để trang của bạn, và thêm trẻ em (hoặc điều khiển asp.net hay html thô) sẽ được hiển thị bên trong div của bạn.

Tất nhiên, css sẽ được thêm vào để tạo kiểu hộp tròn.

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