This blog will probably get updated (even more) infrequently from now on - the majority of my rantings, favourite links, gossip and tittle-tattle seems to have moved onto my Facebook account.
Yes I've finally succumbed to FB - I blame my smartphone, it makes FB so easy and alluring and before you know it you're hooked ...
So in the unlikely event that you're interested in the more frivolous side of this blog (e.g. everything other than the 'mekking it work in .Net' side), track me down on Facebook!
Friday, 15 April 2011
Delegation, that's what you need ....
There's loads of documentation on how to do delegation in C#, but the vb.net version is just different enough for me to waste a heck of a lot of time before I got it working!
The scenario: a website project in VS2010, .Net 3.5, vb.net. The page contains an UpdatePanel which in turn contains a gridview control. Also on the page is a WebControl with a bunch of checkboxes, dropdownlists, and text boxes.
The task is to wire up the webcontrol so that changing any of the values of the controls in the webcontrol updates the contents of the gridview.
This is, of course, attempting to swim upstream against the tide of page drawing order and event execution order, and updatting parent controls with events on child controls, and all that! After a few minutes research it became obvious that Delegation was the way to go - but then the long haul started to get it going in vb.net .... I'll spare you the wailing and gnashing of teeth and cut straight to how it works.
The webcontrol is called RightMenu.ascx, and the main page is called ViewData.aspx. RightMenu.ascx contains a whole bunch of checkboxes called CB1, CB2, and so forth.
In RightMenu.ascx.vb, at class level, declare the following:
So that's a Delegate, an Event which exposes the Delegate, and a Sub which calls the Event using the RaiseEvent method. Having created the basic building blocks, you can now go ahead and add a call to OnCbUpdate to the CheckChanged handler of each one of your checkboxes as follows:
etc etc. You must set your checkboxes to AutoPostBack = True for the event to be triggered.
That's it for the control.
In the main page (DataView.aspx), if everything is set up right on the WebControl, you will find you can now create a handler for the RightMenu1.evCbUpdate event (assuming the control was aliased as RightMenu1 when you added it to the main page). Select that and the Visual Studio IDE will automatically create the event handler with the correct parameters to match evCbUpdate on the WebControl. This event handler will only need to contain one line of code - a call to the Update method of the UpdatePanel (which must be set to UpdateMode="Conditional").
You are now, basically, home and dry. The Page_LoadComplete has access to the controls on the WebControl (by digging through the Controls collection of the Page), so you can loop through that deciding which checkboxes are checked and react accordingly (in my case by updating the SQL underlying the GridView according to which parameters have been set). What makes this special, though, is that things occur in the 'right' order - changing a checkbox triggers the event, the event calls the delegate, the delegate updates the parent page's UpdatePanel.
The above example shows how to do it with checkboxes, but from there it's easy to get the values of dropdowns, text boxes, and any other control on the WebControl. Hopefully this will save you the hours of frustration I had before I got it working.
The scenario: a website project in VS2010, .Net 3.5, vb.net. The page contains an UpdatePanel which in turn contains a gridview control. Also on the page is a WebControl with a bunch of checkboxes, dropdownlists, and text boxes.
The task is to wire up the webcontrol so that changing any of the values of the controls in the webcontrol updates the contents of the gridview.
This is, of course, attempting to swim upstream against the tide of page drawing order and event execution order, and updatting parent controls with events on child controls, and all that! After a few minutes research it became obvious that Delegation was the way to go - but then the long haul started to get it going in vb.net .... I'll spare you the wailing and gnashing of teeth and cut straight to how it works.
The webcontrol is called RightMenu.ascx, and the main page is called ViewData.aspx. RightMenu.ascx contains a whole bunch of checkboxes called CB1, CB2, and so forth.
In RightMenu.ascx.vb, at class level, declare the following:
Public Delegate Sub delCBUpdate(ByVal sender As String, ByVal e As String)
Public Event evCbUpdate As delCBUpdate
Protected Sub OnCbUpdate(ByVal CBID As String, ByVal e As String)
RaiseEvent evCbUpdate(CBID, e)
End Sub
So that's a Delegate, an Event which exposes the Delegate, and a Sub which calls the Event using the RaiseEvent method. Having created the basic building blocks, you can now go ahead and add a call to OnCbUpdate to the CheckChanged handler of each one of your checkboxes as follows:
Protected Sub CB1_CheckedChanged(sender As Object, e As System.EventArgs) Handles CB1.CheckedChanged
OnCbUpdate("Cb1", CB1.Checked)
End Sub
Protected Sub CB2_CheckedChanged(sender As Object, e As System.EventArgs) Handles CB2.CheckedChanged
OnCbUpdate("Cb2", CB2.Checked)
End Sub
etc etc. You must set your checkboxes to AutoPostBack = True for the event to be triggered.
That's it for the control.
In the main page (DataView.aspx), if everything is set up right on the WebControl, you will find you can now create a handler for the RightMenu1.evCbUpdate event (assuming the control was aliased as RightMenu1 when you added it to the main page). Select that and the Visual Studio IDE will automatically create the event handler with the correct parameters to match evCbUpdate on the WebControl. This event handler will only need to contain one line of code - a call to the Update method of the UpdatePanel (which must be set to UpdateMode="Conditional").
Protected Sub RightMenu1_evCbUpdate(sender As String, e As String) Handles RightMenu1.evCbUpdateNow create the Page_LoadComplete handler. Note that this is the LoadComplete handler, NOT the standard Page_Load. This is where we get round the issues surrounding the order the page and its child controls load in.
upData.Update()
End Sub
You are now, basically, home and dry. The Page_LoadComplete has access to the controls on the WebControl (by digging through the Controls collection of the Page), so you can loop through that deciding which checkboxes are checked and react accordingly (in my case by updating the SQL underlying the GridView according to which parameters have been set). What makes this special, though, is that things occur in the 'right' order - changing a checkbox triggers the event, the event calls the delegate, the delegate updates the parent page's UpdatePanel.
The above example shows how to do it with checkboxes, but from there it's easy to get the values of dropdowns, text boxes, and any other control on the WebControl. Hopefully this will save you the hours of frustration I had before I got it working.
Subscribe to:
Posts (Atom)
