2010-03-24 22 views
9

Tất cả các tên dưới đây là chung chung và không phải là tên thực tế được sử dụng.Các điều khiển được thêm vào trong thiết kế là không có trong Page_Load

Tôi có một UserControl tùy chỉnh với một Panel có chứa một vài Nhãn, cả hai điều khiển .aspx.

.aspx:

<asp:Panel runat="server"> 
    <asp:Label ID="label1" runat="server"> 
    </asp:Label> 
</asp:Panel> 
<asp:Panel runat="server"> 
    <asp:Label ID="label2" runat="server"> 
    </asp:Label> 
</asp:Panel> 

codebehind:

private readonly Object object; 
protected void Page_Load(object sender, EventArgs e) 
{ 
    // These are the lines that are failing 
    // label1 and label2 are null 
    label1.Text = object.Value1; 
    label2.Text = object.Value2; 
} 
public ObjectRow(Object objectToDisplay) 
{ 
    object = objectToDisplay; 
} 

Trên trang khác, trong đoạn code sau, tôi tạo một đối tượng mới của điều khiển người dùng tùy chỉnh.

protected void Page_Load(object sender, EventArgs e) 
{ 
    Usercontrol control = new UserControl(object); 
    Controls.Add(control); 
} 

Việc kiểm soát người dùng có tham số và cố gắng để thiết lập các nhãn dựa tắt của đối tượng thông qua vào.

Các nhãn mà nó cố gắng để gán giá trị cho là tuy nhiên, null.

Đây có phải là sự cố vòng đời ASP.net mà tôi không hiểu không? Sự hiểu biết của tôi dựa trên Microsoft ASP.net lifecycle page là các điều khiển trang đã có sẵn sau khi Page_Initialization.

Cách thích hợp để thực hiện việc này là gì? Có cách nào tốt hơn?

EDIT: Từ bên dưới, tôi đã thử sử dụng Page.LoadControl.

Nếu tôi tải điều khiển dựa trên biểu diễn chuỗi của đường dẫn và tên tệp, nó cấm truyền tham số. Tôi có thể phá vỡ điều này bằng cách thêm một phương thức cho phép tôi thiết lập đối tượng. Trong khi điều này làm việc nó cảm thấy hackish. Tôi muốn có thể chuyển giá trị cho hàm tạo nếu điều này là có thể.

Sử dụng phương thức quá tải cho kết quả tương tự như chỉ tải mã phía sau, các nhãn được gán là rỗng.

EDIT: Dường như phương thức quá tải không khởi tạo các điều khiển con được thêm vào tệp .ascx là "theo thiết kế". Tôi tìm thấy điều này trong các ý kiến ​​tại Microsoft's page for Page.LoadControl(type, object[])

+0

Bạn đang sử dụng thuật ngữ khó hiểu. Một điều khiển tùy chỉnh và điều khiển người dùng là những thứ hoàn toàn khác nhau. Một điều khiển người dùng có một mã ascx và một mã phía sau, trong khi một điều khiển tùy chỉnh chỉ đơn giản là một lớp mà hít vào từ lớp System.Web.UI.Control. Bạn đang cố gắng tạo và làm cách nào để thêm chúng vào trang. Bạn đang cố gắng sử dụng cái nào. –

+0

Tôi đang tạo điều khiển người dùng. Tôi sẽ cập nhật mã để phản ánh điều đó. Đối với cách họ đang được thêm vào, tôi đang tạo một thể hiện của điều khiển và sau đó thêm nó vào trang thông qua bộ sưu tập điều khiển của nó. – mwright

Trả lời

11

Khi bạn tạo một thể hiện của mã đằng sau lớp điều khiển người dùng, bạn không tạo một thể hiện của điều khiển người dùng. Điều khiển người dùng thực tế là lớp được tạo từ đánh dấu trong tệp .ascx và lớp đó kế thừa từ mã phía sau lớp.

Nếu bạn muốn tạo điều khiển người dùng động, bạn sử dụng phương thức Page.LoadControl.Nó sẽ tạo ra một thể hiện của điều khiển người dùng nơi mã đằng sau tài liệu tham khảo kiểm soát tương ứng với các điều khiển được tạo ra từ sự đánh dấu:

CustomControl control = (CustomControl)Page.LoadControl("controls/CustomControl.ascx"); 

Nhưng điều đó không cung cấp cho bạn một cơ hội để gửi các thông số để các nhà xây dựng, vì vậy bạn có thể muốn để sử dụng tình trạng quá tải có loại:

CustomControl control = (CustomControl)Page.LoadControl(typeof(CustomControl), new object[] { objectToDisplay }); 

(Tôi không chắc chắn loại tham số thực sự là gì. .)

+1

Trong khi tôi tin rằng những gì bạn đã nói ở đây là chính xác các điều khiển, khi tạo ra bằng cách sử dụng quá tải vẫn đi lên như null khi tôi cố gắng gán giá trị cho họ. Bất kỳ suy nghĩ nào khác? – mwright

+0

@mwright: Nếu bạn sử dụng loại mã phía sau lớp, bạn có cùng một vấn đề như khi bạn tạo một thể hiện của lớp. Bạn phải sử dụng loại của lớp được tạo từ tệp đánh dấu. Tên lớp của điều khiển người dùng dựa trên tên tệp nếu không có thuộc tính 'ClassName' trong chỉ thị' @ Control'. – Guffa

+0

Điều này giúp ích nhiều thời gian. Cảm ơn bạn –

0

Bạn có thể thử gọi EnsureChildControls trong trình xử lý Page_Load của điều khiển tùy chỉnh, mặc dù AFAIK không cần thiết nghiêm túc.

Khi nào/bạn đang thêm điều khiển tùy chỉnh vào bộ sưu tập Điều khiển ở đâu?

10

Sử dụng Chỉ thị đăng ký trong m của bạn hộp kiểm của trang/điều khiển người dùng gốc:

<%@ Register TagPrefix="wb" src="~/CustomControl.ascx" TagName="CustomControl" %> 

<asp:CustomControl runat="server" /> 
+0

Điều này đã khắc phục sự cố tôi gặp phải. Tôi có một tagPrefix được chỉ định trong web.config đã giữ cho trang không bị khiếu nại, nhưng tôi chưa bao gồm chỉ thị đăng ký trên trang (và nó là một điều khiển trong cùng một dự án với một tệp ascx). – davidpricedev

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