Reputation: 3246
I want to wrap up a chunk of HTML render logic in a User Control. Then I want to pass a custom product object (title, thumbnail, id, etc.) to the UserControl that it can use when it renders. Ideally I want to use this in a repeater (or for loop) and pass the current custom product object into the UC.
Every example I've seen has been passing through strings on the UC tag but thats not really want I want to do as it means I'll have references everywhere that need updating should we add a new field that needs rendering.
Any ideas?
.Net 1 using VB.net (not my first choice for .net so go easy)
HTML example to get us going, this would be in the .ascx page:
<div>
<h3><%= myProd.title %></h3>
<img src="<%= myProd.thumbnail %>" />
<p>
<%= myProd.description %>
</p>
</div>
UPDATE:
Ok so with some hacking around here is what I've come up with, its not working though, whats the missing piece of this puzzle?
Create a UserControl and add this to the code behind:
Public Class ProductRender
Inherits System.Web.UI.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
End Sub
Private _product As productItem
Public Property myProd() As productItem
Get
myProd = Me._product
End Get
Set(ByVal Value As productItem )
Me._product = Value
End Set
End Property
End Class
In the UC ascx page I simply have the html above.
In the page that uses the UC I simply added the following for testing:
...usual ascx header stuff...
<%@ Register TagPrefix="ORC" TagName="productRender" Src="productRender.ascx" %>
<ORC:productRender id="Assetrender1" runat="server" asset="<%# getDummyProduct() %>" />
in the code behind I declare getDummyProduct as so:
Public Function getDummyProduct() As productItem
getDummyProduct = New productItem( "DVD Player", "It plays DVDs!", "some_thumb.jpg", 30 )
End Function
Yet in my ascs page I get:"Object reference not set to an instance of an object"
Line 1: <%@ Control Language="vb" AutoEventWireup="false" Codebehind="ProductRender.ascx.vb" Inherits="MyApp.ProductRender" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
Line 2: <h3>
Line 3: <%= myProd.title %>
Line 4: </h3>
Upvotes: 0
Views: 3991
Reputation: 3246
Slaps forehead
Need to call DataBind in Page.OnLoad for the databinding to work, that explains why I was getting Object not found!
Upvotes: 1
Reputation: 73554
I can think of several approaches.
I'd start by asking if you've ever done nested repeaters. If not, start there so that the next thing I'm about to say makes sense. (It's the concept that you need to get first.)
http://support.microsoft.com/kb/306154
You can create your User Control so that it can be databound, and use the concepts from the nested repeaters to datbind this control.
Another viable option would be to use the ItemDataBound event of the repeater to add a control in the code-behind.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.itemdatabound.aspx
A third option would be to create a server side function and put a method call to it in the ItemTemplate
<ItemTemplate>
<%# DisplayProduct(DataBinder.Eval(Container,"DataItem.ProductId")) %>
</ItemTemplate>
...
Public Function DisplayProduct(ByVal ProductID as Integer) AS String
... logic goes here
End Function
All three will work, and there are pros and cons to each. The first option is probably the most "proper" but you'll want to do something you're comfortable with. Personally I'd try all three and see which one performs better.
------------ Added --------------------
I see... I think my wording may be confusing...
What I'm thinking about is making the ascx LOOK like a databound control...
What I've done in the past iscreate a userControl and expose a public property in it.
From the code behind of the ASCX (forgive me if the VB Syntax is off.. I haven't done VB for a few years):
Dim _RecordID as Integer = 0
Public Property RecordId
Get
Return _RecordID
End Get
Set(ByVal Calue as Integer)
_RecordID = Value
End Set
End Property
and the in the Page_Load event of the ascx, put your code to load the data, just like any aspx page, using the RecordID property.
Then on the page that HOSTS the ASCX file
<%@ Register TagPrefix= = "dds" TagName="ProductControl" .... %>
<ItemTemplate>
<dds:ProductControl RecordId = '<%# (DataBinder.Eval(Container,"DataItem.ProductId")) %>'
</ItemTemplate>
Upvotes: 2