I thought I’d make available an interesting piece of code that came about recently because I was using a Telerik Radstrip to display information that was all based on a single piece of data, in that case a Fiscal Year. I decided to remove the Telerik aspect of this tutorial to make it available to a much broader audience but the theory remains.
In this scenario, we have a combobox that’s filled with all the OrderID from the database. When we choose a specific order, we want all the related data displayed. Now this is fairly straightforward but I thought I’d try and show how we did this using User Controls. The goal, in this specific instance was to allow multiple programmers to work on maultiple parts of the project simultaneously, to that end, we broke up the project into modules and created user controls for each. This was each programmer was responsible for his/her code and could checkin/out at their leisure with breaking the overall project. However, this led us to need a way to handle the Events from the Parent control, which was then cascaded down to each Child control.
Why Delegate Methods?
Originally we were using Parent.Parent.Findcontrol.etc but I have to tell you, that got old pretty quickly, especially when alot of the Child Controls had multiple items (radgrids, dropdowns, etc.) that needed to know what Fiscal Year we were talking about. After a few weeks of the design getting deeper and deeper into complexity, one of us broke off and built this method of broadcasting changes down to the Child Controls, rather than the Child Controls always trying to decipher if a change has occurred.
We built our Default.aspx page first and registered our (not yet existing) controls just so we could all have a base project to work in.
<%@ Register TagPrefix="ucHeader" TagName="HeaderControl" Src="~/userControls/headerControl.ascx" %> <%@ Register TagPrefix="ucClients" TagName="ClientsControl" Src="~/userControls/clientsControl.ascx" %> <%@ Register TagPrefix="ucProducts" TagName="ProductsControl" Src="~/userControls/productControl.ascx" %>
Then we created a generic layout which assembled the user controls.
<table class="gridtable" style="width:100%;"> <thead> <tr> <td colspan="2"> <ucHeader:HeaderControl runat="server" ID="HeaderControl" /> </td> </tr> </thead> <tbody> <tr> <td style="width:40%;vertical-align:top" > <ucClients:ClientsControl runat="server" ID="ClientsControl" /> </td> <td style="width:60%;" > <ucProducts:ProductsControl runat="server" ID="ProductsControl" /> </td> </tr> </tbody> </table>
That was pretty much it for that page. At this point each of the programmers could start assembling their code with the knowledge that there eventually would be an object of type Order passed to them, but for now we would hard code anything we needed.
Broadcasting a change
This is where about half the magic happens. The markup itself is uninteresting with only a single dropdownlist which will display the OrderIDs. Lets look at the codebehind though.
Ignoring the code which populates the dropdownlist, let’s look at the code specific to this example.
Public Delegate Sub BroadcastSelectedOrderEvent(SelectedOrder As Order) Public Event BroadcastSelectedOrder As BroadcastSelectedOrderEvent Private Sub Orderscombo_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Orderscombo.SelectedIndexChanged BroadcastValues(sender) End Sub Private Sub BroadcastValues(ByVal sender As DropDownList) Using ctx As New EverymanDatabaseEntities Dim _Order As Order = ctx.Order.Where(Function(x) x.OrderId = sender.SelectedValue).SingleOrDefault RaiseEvent BroadcastSelectedOrder(_Order) End Using End Sub
We create a Delegate method that exposes a Broadcast event and Pass along an entire object of type Order.
We create a Public Event that exposes that a Broadcast has occured (something has been picked from the dropdownlist) that the Parent page can see.
When SelectedIndexChanged fires, we call BroadcastValues which creates the object of type Order based on the dropdownlist’s SelectedItem.value.
Lastly, we manually Raise and Event called BroadcastSelectedOrder and pass it the Order Object.
In order for the line above to work, we need a new line on the Parent Page’s Page_Load which creates a Handler for the Event of the Header’s Dropdownlist and handles it in the Child control.
AddHandler HeaderControl.BroadcastSelectedOrder, AddressOf ProductsControl.ReceiveSelectedOrderBroadcast
Now quite clear yet? It’s ok, it took us a day or two to come up with this scenario. Essentially, the Default page is given Event Handlers for the Dropdownlist in its child control, which are tactfully handled in THEIR child controls…its pretty kool actually. Trust me.
Receiving the Broadcast
In the Child controls of the Header control, all we really need this to receive the Broadcast, as indicated in the Default Page_Load .
Public Sub ReceiveSelectedOrderBroadcast(ByVal _SelectedOrder As Order) FilltheRepeater(_SelectedOrder) End Sub
That’s pretty much it. At this point, the Order is passed onto the child control. Obviously there’s still a lot of work to be done, but as far as passing the information down from the Header control, we’re done.
Using a Delegate was a no-brainer once the project started getting more and more complex and it caused us to step back and look at what information needed to be shared across the 6 or so Child controls we had. Once we had taken the time to assemble the data that needed to be passed down to the child controls, the individual programmers were able to work in silos, knowing fully that the code would work upon checkin because their code was reacting to a change that was handed down to them on a silver platter.
I’ve made an entire solution available with a fully functioning example to get you started off on the right foot.
If you have any suggestions, tips or comments, please feel free to comment below and I’ll respond as soon as I can. Please be sure to download the Zip at the bottom of this article, it contains all the Source code needed for this project.
If you found this article helpful, please consider clicking on one of my sponsors, it’s what pays the bills here.