Geeks With Blogs

News My Blog has been MOVED to https://mfreidge.wordpress.com
Michael Freidgeim's OLD Blog My Blog has been MOVED to https://mfreidge.wordpress.com

The .NET 2.0 provides   System.Web.UI.WebControls.BaseDataBoundControl  and  DataBoundControl classes that can be useful for Custom Data-Bound Web Server Controls  . However it often convinient to have User Control with similar data-binding capabilities.
Unfortunetely .Net doesn't allow multiple inheritance, so I have to duplicate the functionality in my DataBoundUserControl class derived from UserControl class.  

At the moment the DataBoundUserControl class is not fully implemented.As it explained in “Data Source Controls - Under the Hood” , data-bound control has to use a wrapper class in order to expose the DataSource as a data source control (ReadOnlyDataSource that implements IDataSource, returning a view (ReadOnlyDataSourceView) that only supports the select method). MS made ReadOnlyDataSource and ReadOnlyDataSourceView not public, so we need to re-invent them if needed.
As a shortcut derived User Controls should overide PerformSelectDataBinding() 
method.

Imports Microsoft.VisualBasic

Imports System.ComponentModel

'Based on http://msdn2.microsoft.com/en-us/library/ms366539.aspx article "Developing Custom Data-Bound Web Server Controls for ASP.NET 2.0"

Public Class DataBoundUserControl

    Inherits System.Web.UI.UserControl

    True), DefaultValue(CStr(Nothing))> _

    Public Overridable Property DataSource() As Object

        'from http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.basedataboundcontrol.datasource.aspx

        ' When you set the DataSource property, the ValidateDataSource method is called. In addition, if the data-bound control has already been initialized, the OnDataPropertyChanged method is called to set the RequiresDataBinding property to true.

        Get

            Return m_dataSource

        End Get

        Set(ByVal value As Object)

            If (Not value Is Nothing) Then

                ValidateDataSource(value)

            End If

            m_dataSource = value

            OnDataPropertyChanged()

        End Set

    End Property

    Private m_dataSource As Object

 

    Public Overridable Property DataSourceID() As String

        Get

            Dim o As Object = ViewState("DataSourceID")

            If (Not o Is Nothing) Then

                Return CStr(o)

            End If

            Return String.Empty

        End Get

        Set(ByVal value As String)

            ViewState.Item("DataSourceID") = value

            OnDataPropertyChanged()

        End Set

    End Property

    Protected Property RequiresDataBinding() As Boolean

        Get

            Return m_requiresDataBinding

        End Get

        Set(ByVal value As Boolean)

            m_requiresDataBinding = value

            If (m_preRendered AndAlso m_requiresDataBinding = True) Then

                Me.EnsureDataBound()

            Else

            End If

        End Set

    End Property

    Private m_requiresDataBinding As Boolean

    Protected Overridable Sub ValidateDataSource( _

    ByVal dataSource As Object _

    )

        'from ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.en/cpref16/html/M_System_Web_UI_WebControls_DataBoundControl_ValidateDataSource_1_b4c5a2da.htm

        'The DataBoundControl class checks the type of the object that is set for the DataSource property to ensure that it is an instance of the IDataSource, IListSource, or IEnumerable interface.

        If (((Not dataSource Is Nothing) AndAlso Not TypeOf dataSource Is IListSource) AndAlso (Not TypeOf dataSource Is IEnumerable AndAlso Not TypeOf dataSource Is IDataSource)) Then

            Throw New InvalidOperationException("DataBoundControl Invalid DataSource Type" & dataSource.GetType.ToString())

        End If

 

    End Sub

    Protected Overridable Sub OnDataPropertyChanged()

        RequiresDataBinding = True

    End Sub

 

 

    'Calls the DataBind method if the DataSourceID property is set and the data-bound control is marked to require binding.

    'Does nothing if DataSource is used

    'The EnsureDataBound method is called during the OnPreRender method, to call the DataBind method if the data-bound control is not yet bound.

    'The EnsureDataBound method might also be called during calls to CreateChildControls and LoadPostData methods.(?? -not tested yet)

    Protected Overridable Sub EnsureDataBound()

        If (RequiresDataBinding And IsBoundUsingDataSourceID()) Then

            Me.DataBind()

        End If

     End Sub

    'Overrides the Control.OnPreRender event handler to call EnsureDataBound before calling the base class OnPreRender method.

    'invokes data-binding logic as late as possible during the page life cycle and only when needed

    Protected Overrides Sub OnPreRender(ByVal e As EventArgs)

        m_preRendered = True

        EnsureDataBound()

        MyBase.OnPreRender(e)

        m_preRendered = False

    End Sub

    Private m_preRendered As Boolean = False

    Protected ReadOnly Property IsBoundUsingDataSourceID() As Boolean

        Get

            Return (DataSourceID.Length > 0)

        End Get

    End Property

    Public Overrides Sub DataBind()

        PerformSelect()

    End Sub

    Protected Sub MarkAsDataBound()

        ViewState("DataBound") = True

    End Sub

 

    Protected Overridable Sub PerformSelect()

 

        ' Call OnDataBinding here if bound to a data source using the DataSource property (instead of a DataSourceID) because the

        ' data-binding statement is evaluated before the call to GetData.

        If Not IsBoundUsingDataSourceID Then

            OnDataBinding(EventArgs.Empty)

        End If

 

        PerformSelectDataBinding()

        ' The PerformDataBinding method has completed.

        RequiresDataBinding = False

        MarkAsDataBound()

 

        ' Raise the DataBound event.

        'Not implemented yet OnDataBound(EventArgs.Empty)

    End Sub 'PerformSelect

 

    Protected Overridable Sub PerformSelectDataBinding()

        Throw New NotImplementedException(" should be overridde in derived class")

        '' The GetData method retrieves the DataSourceView object from the

        '' IDataSource associated with the data-bound control.

        'TODO  according to http://www.manuelabadia.com/blog/PermaLink,guid,678ed6d8-dce8-40d7-9117-0ffd016fe886.aspx

        'it has to use a wrapper class in order to expose the DataSource as a data source control (ReadOnlyDataSource that implements IDataSource, returning a view (ReadOnlyDataSourceView) that only supports the select method).

        'Unfortunately, MS made ReadOnlyDataSource and ReadOnlyDataSourceView not public, so we need to re-crete them if needed

        'GetData().Select(CreateDataSourceSelectArguments(),  AddressOf OnDataSourceViewSelectCallback)

    End Sub 'PerformSelect

End Class

 

 

Posted on Monday, September 25, 2006 8:56 AM | Back to top


Comments on this post: ASP.NET Data Bound UserControl

# re: ASP.NET Data Bound UserControl
Requesting Gravatar...
Any new discoverings on this subject since this post?

Is this the only way I can take 4 databound DropDownLists that I need to spread over numerous pages and create a usercontrol of them?

:-/
Left by Tommy on Nov 29, 2007 3:03 AM

# re: ASP.NET Data Bound UserControl
Requesting Gravatar...
If you are making a specific DropDownList with specific entries tied to a specific DataSource, without needing the ability for declarative selection of the DataSource in the parent page, then you would just need to create a usercontrol that contains both the DropDownList and the corresponding DataSource within it. Then just bind the DropDownList to the DataSource, and then embed the usercontrol wherever you need it to be.

Example:
[MyDropDownList.ascx]
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyDropDownList.ascx.cs" Inherits="MyDropDownList" %>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT * FROM myTable"></asp:SqlDataSource>
<asp:DropDownList ID="DropDownList1" runat="server" DataTextField="myTextField" DataValueField="myValueField" DataSourceID="SqlDataSource1">
</asp:DropDownList>

[MyWebPage.aspx source]
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyWebPage.aspx.cs" Inherits="MyWebPage" %>
<%@ Register Src="~/MyDropDownList.ascx" TagPrefix="uc1" TagName="MyDropDownList" %>

<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:MyDropDownList ID="MyDropDownList1" runat="server" />
</div>
</form>
</body>
</html>

If these 4 DropDownLists that you mention each have different DataSource's, then there doesn't seem to be any specialized functionality you are trying to achieve by making them into user controls. In this case, they should just remain DropDownList's with DataSource's attached right in the source pages where these 4 DropDownList's go.
Left by kurt on Dec 31, 2007 7:02 AM

# re: ASP.NET Data Bound UserControl
Requesting Gravatar...
Hey, that was interesting,

you wrote this article so well

Thanks for writing about it
Left by web development company on Aug 17, 2009 11:53 AM

# re: ASP.NET Data Bound UserControl
Requesting Gravatar...
Hi, did you manage to complete your user control? I've searched for days on end and finally found your blog which helps alot. I got a custom gridview and I set the datasource to a datatable. In the gridview class I need to rebind the grid to the datasource to do an export to excel function. if i try Dim ds = Me.GetDataSource i get the typeof datasource is system.web.ui.webcontrols.readonlydatasource. I cant access the select method or anything in order to rebind. Please advise me as I cannot find any other documentation. Thanks
Left by Nitesh on Nov 16, 2011 6:24 AM

# re: ASP.NET Data Bound UserControl
Requesting Gravatar...
Just stumbled your blog and found it useful and it's well lead out thanks
Left by Web Developments on Sep 13, 2012 1:26 AM

Your comment:
 (will show your gravatar)


Copyright © Michael Freidgeim | Powered by: GeeksWithBlogs.net