Solved

How to add handler to custom user control datalist itemcommand?

Posted on 2009-03-31
13
2,720 Views
Last Modified: 2013-12-17
Hi,
I'd created a custom user control with a datalist (with button in itemtemplate) and a button.

I can NOT get the itemcommand event to work, but i 'm able to get the onclick event to work though. Did i missed out anything?

Any help is greatly appreciated.

AddHandler btn.Click, AddressOf btnDatalist_Click                ' I can get this button to work
AddHandler dtl.ItemCommand, AddressOf dtlYoutube_ItemCommand     ' This is NOT working :(

.aspx.vb

===========

    Protected Overloads Overrides Sub OnPreInit(ByVal e As EventArgs)

            If ctrl.GetType.ToString.Equals("ASP.UserCtrlDatalist") Then
 

                Dim ctrlDatalist As UserCtrlDatalist = ctrl
 

                Dim btn As Button = ctrlDatalist.FindControl("Button1")

                Dim dtl As DataList = ctrlDatalist.FindControl("dtlYoutube")
 

                AddHandler btn.Click, AddressOf btnDatalist_Click                ' I can get this button to work

                AddHandler dtl.ItemCommand, AddressOf dtlYoutube_ItemCommand     ' This is NOT working :(
 
 

            End If

End Sub
 

    Private Sub btnDatalist_Click(ByVal sender As Object, ByVal e As EventArgs)

        MsgBox("this is button")

    End Sub
 

    Private Sub dtlYoutube_ItemCommand(ByVal sender As Object, ByVal e As EventArgs)

        MsgBox("this is button in the datalist")

    End Sub
 
 

.ascx

============

 

<%@ Control Language="VB" ClassName="UserCtrlDatalist" AutoEventWireup="True" CodeFile="DatalistItemTemplate.ascx.vb" Inherits="DatalistItemTemplate" %>

 

<asp:TextBox ID="txtVideo" runat="server" />

 

<asp:DataList ID="dtlYoutube" runat="server" 

            DataKeyField="strYoutubeUrl" 

            RepeatColumns = "3">

    <HeaderTemplate>

        <strong>Youtube Video Search Result</strong>

    </HeaderTemplate>

    <ItemTemplate>

        Title: <%#DataBinder.Eval(Container.DataItem, "strTitle")%>

        <br />

        <%#DataBinder.Eval(Container.DataItem, "strYoutubeVideo")%>

        <!--<br />

        Url: <%#DataBinder.Eval(Container.DataItem, "strYoutubeUrl")%>-->

        <br />

        <asp:Button ID="btnSetPrimary" runat="server" CommandName="set_primary" Text="Get Video" />

        <br /><br />

    </ItemTemplate>

</asp:DataList>
 

<asp:Button ID="Button1" runat="server" Text="get text box" />

Open in new window

0
Comment
Question by:tangteng78
  • 7
  • 6
13 Comments
 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
The handler for dtlYoutube_ItemCommand should take a parameter of type DataListCommandEventArgs
0
 

Author Comment

by:tangteng78
Comment Utility
No luck, tried that, the events are not being fired (used the debug to trace the flow).
Any other idea?
0
 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
Ah sorry I missed the point of what you were trying to do before.
I think the usual thing to do for this kind of scenario is to declare an event for your user control itself, handle the datalist event inside the user control then raise your control's event from inside that event handler.

So something like:

public Event DataListCommand as DataListCommandEventHandler

private Sub dtlYoutube_Command(sender as object, e as DataListCommandEventArgs) Handles dtlYoutube.ItemCommand
     RaiseEvent DataListCommand(Me, e)
End Sub

Then in your aspx handle this event rather than trying to find the datalist within the ascx itself.
0
 

Author Comment

by:tangteng78
Comment Utility
Hi Nazo,
Sorry, I'm pretty new. The snippet codes you provided, do i code it in the .ascx or in the .aspx? If you could provide a working code example, it would be greatly appreciated.

Thanks.
0
 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
The code goes inside the ascx file. You should then be able to handle this event by using AddHandler as you have already done in your aspx PreInit. Replace
AddHandler dtl.ItemCommand, AddressOf dtlYoutube_ItemCommand
With:
AddHandler dtl.DataListCommand, AddressOf dtlYoutube_ItemCommand

I can't really give you a working example as I don't have enough code to reproduce everything required.
0
 

Author Comment

by:tangteng78
Comment Utility
Hi Nazo,
I' added in the codes to the .ascx. But when i try to add the handler in the .aspx, i have the error below (see attached jpeg file).

Basically it's complaining about "datalistcommand is nto an event of System.Web.UI.WebControls.Datalist".

Please advise.

error.jpg
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
Sorry my fault, I didn't read your code correctly.
AddHandler dtl.DataListCommand, AddressOf dtlYoutube_ItemCommand should read:
ctrl.DataListCommand, AddressOf dtlYoutube_ItemCommand

Assuming ctrl is the ID you gave your user control.
0
 

Author Comment

by:tangteng78
Comment Utility
Hi NazoUK,
No luck. I'm already at wit's end, so I'm attaching the file codes.


Due to .dll files are disallowed, i can't attached the youtube api .dll. Basically the codes are to provide user to add in video search module dynamically. If there's a need for you to download the .dll go to this link:

1) http://code.google.com/p/google-gdata/downloads/list

2) Download the .msi.

Really hope you are able to help me to spot if I'd missed out anything in the codes. Appreciate it and thanks.

default3.aspx.vb

=================

Imports ASP

Imports System.Data
 

'Google Gdata API namespaces

Imports Google.GData.Client

Imports Google.GData.Extensions

Imports Google.GData.YouTube
 

Partial Class Default3

    Inherits System.Web.UI.Page

    Shared intCtrlID As Integer

    Shared lstCtrls As New List(Of Control)
 

    'Constant to take separate 3 snippets + videofeed url to form a full Youtube player url string

    'Snippet 1 :

    Private Const strYoutube1 As String = "<object width=""200"" height=""161""><param name=""movie"" value="""

    'Snippet 2 : url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

    'Snippet 3 :

    Private Const strYoutube2 As String = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0""></param><param name=""allowFullScreen"" value=""false""></param><embed src="""

    'Snippet 4 : url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

    'Snippet 5 :

    Private Const strYoutube3 As String = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0"" type=""application/x-shockwave-flash"" allowfullscreen=""false"" width=""200"" height=""161""></embed></object>"
 
 

    Protected Overloads Overrides Sub OnPreInit(ByVal e As EventArgs)

        For Each ctrl As Control In lstCtrls
 

            'Assign customized handler event to button control.

            If ctrl.GetType.ToString.Equals("System.Web.UI.WebControls.Button") Then

                Dim btn As Button = ctrl
 

                If Regex.IsMatch(btn.ID.ToString, "_btnYoutubeSearch") Then

                    AddHandler btn.Click, AddressOf btnYoutubeSearch_Click
 
 

                End If

            ElseIf ctrl.GetType.ToString.Equals("ASP.UserCtrlDatalist") Then
 

                Dim ctrlDatalist As UserCtrlDatalist = ctrl
 

                Dim btn As Button = ctrlDatalist.FindControl("Button1")

                Dim dtl As DataList = ctrlDatalist.FindControl("dtlYoutube")
 

                AddHandler btn.Click, AddressOf btnDatalist_Click

                AddHandler ctrlDatalist.DataListCommand, AddressOf dtlYoutube_ItemCommand   'WELL, NOTHING HAPPENS WHEN VIDEO SELECTED
 

            End If
 

            'Then add the controls to the page

            PlaceHolder1.Controls.Add(ctrl)
 

            'Note the MyBase.OnPreInit(e) call which makes sure the base method is also called in 

            'addition to any functionality you wish to present. 

            MyBase.OnPreInit(e)
 

        Next
 

    End Sub
 

    Protected Sub Add_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Add.Click

        '1) Increment the counter ID

        intCtrlID += 1
 

        '2) Define web controls

        '... a button

        Dim btnYoutubeSearch As New Button

        btnYoutubeSearch.Text = "Search Youtube file"

        btnYoutubeSearch.ID = "_btnYoutubeSearch" + intCtrlID.ToString
 

        '... a textbox

        Dim txtYoutubeSearch As New TextBox

        txtYoutubeSearch.ID = "_txtYoutubeSearch" + intCtrlID.ToString

        txtYoutubeSearch.Text = "_txtYoutubeSearch" + intCtrlID.ToString
 

        'Dim dtlYoutube As New GridView

        'dtlYoutube.ID = "_dtlYoutube" + intCtrlID.ToString
 

        Dim dtlYoutube1 As New UserCtrlDatalist

        dtlYoutube1.ID = "_dtlYoutube1" + intCtrlID.ToString
 
 

        '... a label. This serves only as a newline.

        Dim lblNewLine1 As New Label

        lblNewLine1.ID = "_lblNewLine1" + intCtrlID.ToString

        lblNewLine1.Text = "<br>"
 

        '#TIPS: Basically on every click to add new control, it will go to page_onload (pagepostback) -> add_new_control event

        '3) And add the same web controls with same sequence to control lists.

        'Controls are renumerated and will be added in next page postback.

        lstCtrls.Add(txtYoutubeSearch)

        lstCtrls.Add(btnYoutubeSearch)

        lstCtrls.Add(dtlYoutube1)

        lstCtrls.Add(lblNewLine1)
 
 

        '4) Add all web controls to the page placeholder. Sequence from top - bottom.

        'Controls are added in real time.

        PlaceHolder1.Controls.Add(txtYoutubeSearch)

        PlaceHolder1.Controls.Add(btnYoutubeSearch)

        PlaceHolder1.Controls.Add(dtlYoutube1)

        PlaceHolder1.Controls.Add(lblNewLine1)
 

    End Sub
 
 

    'The following 3 subroutines are custom events, which will be handler-added in the pre-init.

    'When user search for video, this subroutine will be triggered.

    Private Sub btnYoutubeSearch_Click(ByVal sender As Object, ByVal e As EventArgs)
 

        Dim btn As Button = sender                      'Define all the web controls

        Dim dtl As New GridView

        Dim dtl1 As New UserCtrlDatalist
 

        Dim txt As New TextBox

        'Dim img As New System.Web.UI.WebControls.Image

        Dim arrControlID(1) As String                   'Array to take split string. (1) element represent web control numeric ID
 
 

        'Get the numeric ID tied to the web control. Will be used to check other web controls are in the same group.

        'Eg: _btnUpload1 -> _imgUpload1 -> _txtDetails_1

        arrControlID = Regex.Split(btn.ID.ToString, "_btnYoutubeSearch")
 

        'This is for debug purpose.

        lblGetControl.Text = "You'd selected -> " + btn.ID.ToString + "with ID of :" + arrControlID(1)
 

        'Renumerate all dynamically added controls in the control list. 

        For Each ctrl As Control In lstCtrls
 

            'We are ONLY interested to look for Image & FileUpLoad web control.

            If ctrl.GetType.ToString.Equals("System.Web.UI.WebControls.TextBox") Then
 

                txt = ctrl
 

            ElseIf ctrl.GetType.ToString.Equals("ASP.UserCtrlDatalist") Then
 

                dtl1 = ctrl
 

                'Now we have gotten both the Image and FileUpLoad control, we reconfirm that both have same ID

                If Regex.IsMatch(txt.ID.ToString, "_txtYoutubeSearch" & arrControlID(1)) And Regex.IsMatch(dtl1.ID.ToString, "_dtlYoutube1" & arrControlID(1)) Then
 

                    'Start the search, bind the result to datalist

                    dtl1.CreateDataSource(txt.Text)

                    dtl1.DataBind()
 

                End If
 

            End If
 

        Next

        Try
 

        Catch ex As Exception

            Response.Write(ex)

        End Try
 

    End Sub
 

    'When a user click on a button in the custom user control.

    Private Sub btnDatalist_Click(ByVal sender As Object, ByVal e As EventArgs)

        MsgBox("You have clicked a button from the custom user control")
 

    End Sub
 

    'Get the video url selected by user

    'When user selected a video from the datalist, this 'should be triggered', BUT IT'S NOT :(

    Private Sub dtlYoutube_ItemCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs)

        'Private Sub dtlYoutube_ItemCommand(ByVal sender As Object, ByVal e As EventArgs)

        MsgBox("You have click on the button in the datalist. Can't get this to work though :(")

        lblGetControl.Text = "You have click on the button in the datalist. Can't get this to work though :("

    End Sub
 

End Class
 
 

default3.aspx

===============

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default3.aspx.vb" Inherits="Default3" %>

<%@ Register TagPrefix="Acme" TagName="Message" Src="DatalistItemTemplate.ascx" %>
 
 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:Button ID="Add" runat="server" Text="Add Youtube Search Module" style="height: 26px" /><br />

        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>

        <br />

        <asp:TextBox ID="TextBox1" runat="server" Text="This is just a dummy textbox"/>

        <br />

    </div>

    

    <asp:Label ID="lblGetControl" runat="server" Text="Click button below to get all the dynamic generated textbox values"/>

    <br />

    <asp:Button ID="btnGetTextBox" runat="server" Text="Get textbox value" />

    </form>

</body>

</html>
 
 

DatalistItemTemplate.ascx.vb

==============================
 

Imports System.Data
 

'Google Gdata API namespaces

Imports Google.GData.Client

Imports Google.GData.Extensions

Imports Google.GData.YouTube
 
 
 

Partial Class DatalistItemTemplate
 

    Inherits System.Web.UI.UserControl
 

    Public Event DatalistCommand As DataListCommandEventHandler
 

    'Constant to take separate 3 snippets + videofeed url to form a full Youtube player url string

    'Snippet 1 :

    Private Const strYoutube1 As String = "<object width=""200"" height=""161""><param name=""movie"" value="""

    'Snippet 2 : url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

    'Snippet 3 :

    Private Const strYoutube2 As String = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0""></param><param name=""allowFullScreen"" value=""false""></param><embed src="""

    'Snippet 4 : url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

    'Snippet 5 :

    Private Const strYoutube3 As String = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0"" type=""application/x-shockwave-flash"" allowfullscreen=""false"" width=""200"" height=""161""></embed></object>"
 

    'Get the video url selected by user

    Protected Sub dtlYoutube_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) Handles dtlYoutube.ItemCommand

        RaiseEvent DatalistCommand(Me, e)

    End Sub
 
 

    Function CreateDataSource(ByVal strQuery As String) As ICollection
 

        ' Create sample data for the DataList control.

        Dim dt As DataTable = New DataTable()

        Dim dr As DataRow
 

        ' Define the columns of the table.

        'GetType format for integer or double is GetType(Int32) and GetType(Double) respectively.

        dt.Columns.Add(New DataColumn("strTitle", GetType(String)))

        dt.Columns.Add(New DataColumn("strYoutubeVideo", GetType(String)))

        dt.Columns.Add(New DataColumn("strYoutubeUrl", GetType(String)))

        '---------------------------------------------------------------------------

        'YOUTUBE API STARTS HERE

        '---------------------------------------------------------------------------

        'Variables to take separate 3 snippets + videofeed url to form a full Youtube player url string

        'Dim strYoutube1, strYoutube2, strYoutube3, strYoutubeFullString As String

        Dim strYoutubeFullString As String
 

        'Developer's Client ID and Key to access Youtube database.

        Dim clientID As String = "ytapi-EngTengTang-Mypersonalblogan-govojcta-0"

        Dim developerKey As String = "AI39si79Q2oGarqRFEVWDymA_6YEhrqNRAxBNifec0f1WGu2yzOT2nOPEiQrkTCJEIi6H8oaUQz1C-5qpVrw0mUi1SdbPgXBUg"
 

        'And they are...

        'Snippet 1

        'strYoutube1 = "<object width=""200"" height=""161""><param name=""movie"" value="""

        'Snippet 2 = url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

        'Snippet 3 

        'strYoutube2 = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0""></param><param name=""allowFullScreen"" value=""false""></param><embed src="""

        'Snippet 4 = url link to video. Eg: http:'www.youtube.com/v/ma9I9VBKPiw

        'Snippet 5

        'strYoutube3 = "&color1=0xb1b1b1&color2=0xcfcfcf&feature=player_embedded&fs=0&rel=0"" type=""application/x-shockwave-flash"" allowfullscreen=""false"" width=""200"" height=""161""></embed></object>"
 

        Dim feedUrl As String = "http://gdata.youtube.com/feeds/api/videos?q=skateboarding+dog&start-index=1&max-results=5&v=2"
 

        Dim service As New YouTubeService("example app", clientID, developerKey)
 

        Dim query As New YouTubeQuery(YouTubeQuery.DefaultVideoUri)
 

        'The Author method sets the author of the entry.

        'query.Author = "tangteng"

        'The NumberToRetrieve method sets the maximum number of entries to return at one time.

        query.NumberToRetrieve = 6

        'The Query method sets a search query term. Searches for the specified string in all video metadata, such as titles, tags, and descriptions.

        query.Query = strQuery

        'The StartIndex method sets the 1-based index of the first result to be retrieved (for paging).

        query.StartIndex = 1
 

        'YouTubeQuery query = new YouTubeQuery(YouTubeQuery.DefaultVideoUri);
 

        Dim videoFeed As YouTubeFeed = service.Query(query)
 

        'This is where all the magic happens.

        For Each Entry As YouTubeEntry In videoFeed.Entries
 

            '-----------------------------------------------------------------

            'YOUTUBEENTRY ATTRIBUTE/VALUE

            '-----------------------------------------------------------------

            'Response.Write("<p>")

            'Response.Write("<strong>Title: " + Entry.Title.Text + "</strong>")

            'Response.Write("<br>")

            'Response.Write(Entry.Media.Description.Value)

            'Response.Write("<br>")

            'Response.Write("Keywords: " + Entry.Media.Keywords.Value)

            'Response.Write("<br>")

            'Response.Write("Uploaded by: " + Entry.Media.Credit.Value)

            'Response.Write("<br>")
 

            'if (entry.Location != null)

            '{

            '    Response.Write("Latitude: " + entry.Location.Latitude);

            '    Response.Write("<br>");

            '    Response.Write("Longitude: " + entry.Location.Longitude);

            '    Response.Write("<br>");

            '}
 

            'if (entry.Media.Rating != null)

            '{

            '    Response.Write("Restricted in: " + entry.Media.Rating.Country);

            '    Response.Write("<br>");

            '}
 

            'if (entry.IsDraft)

            '{

            '    Response.Write("Video is not live.");

            '    Response.Write("<br>");
 

            '    string stateName = entry.State.Attributes["name"].ToString();

            '    if (stateName == "processing")

            '    {

            '        Response.Write("Video is still being processed.");

            '        Response.Write("<br>");

            '    }

            '    else if (stateName == "rejected")

            '    {

            '        Response.Write("Video has been rejected because: ");

            '        Response.Write(entry.State.Value);

            '        Response.Write("<br>");

            '        Response.Write("For help visit: ");

            '        Response.Write(entry.State.Attributes["helpUrl"]);

            '        Response.Write("<br>");

            '    }

            '    else if (stateName == "failed")

            '    {

            '        Response.Write("Video failed uploading because:");

            '        Response.Write(entry.State.Value);

            '        Response.Write("<br>");

            '        Response.Write("For help visit: ");

            '        Response.Write(entry.State.Attributes["helpUrl"]);

            '        Response.Write("<br>");

            '    }

            '}
 

            'if (entry.EditUri != null)

            '{

            '    Response.Write("Video is editable by the current user.");

            '    Response.Write("<br>");

            '}
 

            'if (entry.Rating != null)

            '{

            '    Response.Write("Average rating: " + entry.Rating.Average);

            '    Response.Write("<br>");

            '}
 

            'SimpleElement statistics = entry.getYouTubeExtension("statistics");

            'if (statistics != null)

            '{

            '    Response.Write("View count: " + statistics.Attributes["viewCount"]);

            '    Response.Write("<br>");

            '}
 

            '*Can't enable this as it will has ambiguous reference to Google.GData.YouTube and

            'Google.GData.Extensions.MediaRss namespaces.

            'So it's either enable the Media.Thumbnails OR Media.Contents

            'Response.Write("Thumbnails:");

            'foreach (MediaThumbnail thumbnail in entry.Media.Thumbnails)

            '{

            '-------------------------------------------------------------------

            'MEDIA.THUMBNAILS ATTRIBUTES/VALUES

            '-------------------------------------------------------------------

            'Response.Write("\tThumbnail URL: " + thumbnail.Attributes["url"]);

            'Response.Write("<br>");

            'Response.Write("\tThumbnail time index: " + thumbnail.Attributes["time"]);

            'Response.Write("<br>");

            '}
 

            'Response.Write("Media:<br>")
 

            For Each MediaContent As MediaContent In Entry.Media.Contents
 

                'Each video feed has 5 displayable video content.

                'Only web displayable video content (format 5). Format 1 and 6 are for handheld video content.
 

                If Convert.ToInt16(MediaContent.Attributes("format")) = 5 Then

                    'Now concat Snippet 1...5 together into 1 full Youtube player string

                    strYoutubeFullString = strYoutube1 + MediaContent.Attributes("url") + strYoutube2 + MediaContent.Attributes("url") + strYoutube3 + "<br>"
 

                    'Capture elements to a new row, then add it to datatable

                    dr = dt.NewRow()

                    dr(0) = Entry.Title.Text

                    dr(1) = strYoutubeFullString

                    dr(2) = MediaContent.Attributes("url")

                    dt.Rows.Add(dr)
 

                End If
 

                '-------------------------------------------------------------------

                'MEDIACONTENT ATTRIBUTES/VALUES

                '-------------------------------------------------------------------

                'Response.Write("\tMedia Location: " + MediaContent.Attributes("url"))

                'Response.Write("<br>")

                'Response.Write("\tMedia Type: " + MediaContent.Attributes("format"))

                'Response.Write("<br>")

                'Response.Write("\tDuration: " + MediaContent.Attributes("duration"))

                'Response.Write("<br>")
 

            Next
 

        Next
 

        dtlYoutube.DataSource = dt

        dtlYoutube.DataBind()
 

        'To enable binding, need it in Dataview format. Please keep this in mind.

        Dim dv As DataView = New DataView(dt)

        Return dv
 
 
 

    End Function
 

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

        MsgBox("output = " & txtVideo.Text)

    End Sub
 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then

            txtVideo.Text = "this is first load"

        Else

            txtVideo.Text = " this is postback"

        End If

    End Sub
 

End Class
 
 

DatalistItemTemplate.ascx.

===========================

<%@ Control Language="VB" ClassName="UserCtrlDatalist" AutoEventWireup="True" CodeFile="DatalistItemTemplate.ascx.vb" Inherits="DatalistItemTemplate" %>
 

<asp:TextBox ID="txtVideo" runat="server" />
 

<asp:DataList ID="dtlYoutube" runat="server" 

            DataKeyField="strYoutubeUrl" 

            RepeatColumns = "3">

    <HeaderTemplate>

        <strong>Youtube Video Search Result</strong>

    </HeaderTemplate>

    <ItemTemplate>

        Title: <%#DataBinder.Eval(Container.DataItem, "strTitle")%>

        <br />

        <%#DataBinder.Eval(Container.DataItem, "strYoutubeVideo")%>

        <!--<br />

        Url: <%#DataBinder.Eval(Container.DataItem, "strYoutubeUrl")%>-->

        <br />

        <asp:Button ID="btnSetPrimary" runat="server" CommandName="set_primary" Text="Get Video" />

        <br /><br />

    </ItemTemplate>

</asp:DataList>
 

<asp:Button ID="Button1" runat="server" Text="get text box" />

Open in new window

0
 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
Sorry I'm having a hard time understanding what your code is trying to achieve. why are you storing all the controls in a shared list? This means one instance of the control will be shared across everyone who accesses the page.

Also what is the type UserCtrlDatalist? I'm assuming it's the user control but it doesn't match the class definition.
0
 

Author Comment

by:tangteng78
Comment Utility
Hi NazoUK,
See my answer below:
1) Shared - I want to hold the instance value so that it will still retain its state on postback. It was never my intention to let other users(everyone) to access/shared it. Is there any way around this ?
2)  UserCtrDatalist - > This refers back to the classname defined in the .ascx.
DatalistItemTemplate.ascx.
===========================
<%@ Control Language="VB" ClassName="UserCtrlDatalist" AutoEventWireup="True" CodeFile="DatalistItemTemplate.ascx.vb" Inherits="DatalistItemTemplate" %>
 
 In short, my page trying to do this:
1) A button for user to click to add a text box + button to search youtube video.
2) if user click on this button, a textbox and button will be added dynamically (can add mulitple times)
3) User enter the search string in textbox, click on the search button and the video result will be displayed on the datalist. A button will be attached to each searched video result.
4) User can select on the video by clicking on this button and 'supposely' it will be able to get the video ID. This is the part that is not working currently.
Btw, do you have an external email? I can zipped up the files and send it to you (plus dll as well). Believe that could save you the trouble of figuring out what my page trying to do :)
Hope this explanation helps.
0
 
LVL 15

Accepted Solution

by:
NazoUK earned 500 total points
Comment Utility
I'm still kinda confused by the ClassName thing. I couldn't get your code to compile because type UserCtrlDatalist is not defined. As far as I understand it ClassName is used when you are not using code behind pages. As you are using code behinds and have Inherits set to DatalistItemTemplate then this is the class name that is used. The ClassName attribute seems to be ignored. Perhaps I'm missing something?

Dynamic controls can be kinda tricky. However, ASP.NET will automatically persist properties of controls in ViewState, when you recreate the dynamic control as long you use the same ID.
I've knocked up a quick demo to demonstrate what I mean. There are 2 buttons to add a dynamic button or textbox to the page. I store the type and ID of each control in user session then use this to recreate the control list each postback.
Note that any text entered in the textboxes is persisted as is the text of the buttons even though it is not explicitly set when I recreate the controls.

I'd rather not post my email address on here but if you can upload your code to a filehosting site or something similar I'll try to take a look at it when I get a minute.
File Default2.aspx.vb
 

Imports System.Data

Imports System.Collections.Generic
 

Partial Class Default2

    Inherits System.Web.UI.Page
 

    Protected Property ctrls() As List(Of String)

        Get

            If Session("ctrls") Is Nothing Then

                Session("ctrls") = New List(Of String)

            End If

            Return CType(Session("ctrls"), List(Of String))

        End Get

        Set(ByVal value As List(Of String))

            Session("ctrls") = value

        End Set

    End Property
 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init

        If Not Page.IsPostBack Then

            ctrls = New List(Of String)

            ctrls.Add("Hello")

        End If

        For Each ctrl As String In ctrls

            Dim c As String() = ctrl.Split("|")

            Select Case c(0)

                Case "Button"

                    Dim btn As Button = New Button()

                    btn.ID = c(1)

                    AddHandler btn.Click, AddressOf btn2_click

                    ph1.Controls.Add(btn)

                    ph1.Controls.Add(New LiteralControl("<br />"))

                Case "TextBox"

                    Dim txt As TextBox = New TextBox()

                    txt.ID = c(1)

                    ph1.Controls.Add(txt)

                    ph1.Controls.Add(New LiteralControl("<br />"))

            End Select            

        Next

    End Sub
 

    Protected Sub btnAddText_Click(ByVal sender As Object, ByVal e As CommandEventArgs) Handles btnAddBtn.Command, btnAddText.Command

        Select Case e.CommandName

            Case "Button"

                Dim btn As Button = New Button

                btn.ID = "ctrl" & ctrls.Count

                ph1.Controls.Add(btn)

                'Must add control to placeholder BEFORE Changing properties such as Text or they won't be persisted on postback

                btn.Text = "Button " + btn.ID

                ctrls.Add(String.Format("{0}|{1}", "Button", btn.ID))                

            Case "TextBox"

                Dim txt As TextBox = New TextBox

                txt.ID = "ctrl" & ctrls.Count

                ctrls.Add(String.Format("{0}|{1}", "TextBox", txt.ID))

                ph1.Controls.Add(txt)

        End Select        

    End Sub
 

    Protected Sub btn2_click(ByVal sender As Object, ByVal e As EventArgs)

        Dim btn As Button = CType(sender, Button)

        ph2.Controls.Add(New LiteralControl(btn.ID & " Clicked!<br />"))

    End Sub

End Class
 

File default2.aspx
 

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default2.aspx.vb" Inherits="Default2" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:PlaceHolder runat="server" ID="ph1" /><br />

        <asp:PlaceHolder runat="server" ID="ph2" />

        <asp:Button runat="server" ID="btnAddBtn" Text="Add Button" CommandName="Button" /> 

        <asp:Button runat="server" ID="btnAddText" Text="Add Text" CommandName="TextBox" />

    </div>

    

    </form>

</body>

</html>

Open in new window

0
 
LVL 15

Expert Comment

by:NazoUK
Comment Utility
Sorry typo in the above. Should have read:

However, ASP.NET will automatically persist properties of controls in ViewState, and will restore the state when you recreate the dynamic control as long you use the same ID.
0
 

Author Closing Comment

by:tangteng78
Comment Utility
I'd created a simple page with just a datalist with buttons on it. Even clicking on the button doesn't fired up the itemcommand events. So i believe this could be a different problem all together, will post this question in another posting.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now