Thursday, 5 July 2007

Master FindControl

A web project I am developing has nested Master Pages.

Within Main Master Page has two ContentPlaceHolder with IDs ContentPlaceHolder1 and ContentPlaceHolder2 respectively.

Within ContentPlaceHolder1 resides another Master Page which I will name it as Second Master Page for an easy usage. The Second Master Page has one ContentPlaceHolder with ID called ContentPlaceHolder2.

Under the Second Master Page's ContentPlaceHolder2 is the page I'm working on which I will name it as XX.aspx.

XX.aspx contains custom composite controlsthat are checkboxes and dropdownlists.

What I would like to do is: after clicking on SAVE button, the data related to the checked checkboxes and its related dropdownlist options will be stored in the database.

The VIEWSTATE of the custom controls are kept on POSTBACK and all I need to do is to look for those custom controls on XX page and get the data.

I first tried to get content place holder control on XX page by using the following code:

ContentPlaceHolder _content = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder2");

However, that code returns NULL.

After figuring out what it does for some times, I changed the code as:

ContentPlaceHolder _pcontent = (ContentPlaceHolder)Master.Master.FindControl("ContentPlaceHolder1");
ContentPlaceHolder _content = (ContentPlaceHolder)_pcontent.FindControl("ContentPlaceHolder2");


if (_content != null)
{
x x x
}


Now I understand that in order to avoid the ambiguous ContentPlaceHolder ID names in nested Master Page, I shall start searching from the top parent Master Page.

Now I'm satisfied that I can retrieve data from the controls on my XX page :)

Monday, 2 July 2007

Page_Render and Custom composite web controls

I created web custom composite controls which contain CheckBoxes.

In order to make it display after PostBack, its building-function has to be in Page_Init() or Page_Load() before calling LoadViewState of the Page.

As the custom control has a checkbox and it needs to be in the same condition before the postback (for example, if the checkbox is ticked, then after postback, it should be ticked too), I was putting the code for the checkbox selection in Page_PreRender().

As the PreRender is called last time before the display, I thought it would refill the checkboxes correctly. However, the checkboxes which were checked before the postback were unchecked after the postback.

I realised later it was because the PreRender or Render is called after LoadViewState of the Page and thus it cannot find the custom controls in the ViewState of that Page.

Thus, I changed it back into Page_Load and now it works properly.

Another thing is, when you want your custom controls to be in ViewState, do not put its built code into “if (!IsPostBack){ }”.

Learn another lesson again J

Web Composite Control

I'm using .NET 2.0 to build web applications.
At the moment I am modifying a page which generates checkboxes and dropdownlists when the main dropdown option changes.
I used CheckBoxList and dynamic dropdownlist to display as follows:

CheckBoxList1 Dropdownlists CheckBoxList2 Dropdownlists

However, as I put them in the alignments between the related checkbox and dropdownlist, the layout was not great and completely out of line. That was because I calculated the margin-top of the dropdown to make it align with the checkbox.

So, in order to fix it, I created custom web controls which group checkbox and dropdownlist and again group those entire composite controls as a list.

Then, what I need to do is when you click on the checkbox, the text of the checkbox is to be changed. I used Javascript and applied the font style as o.style.fontWeight = "bold". However, although it changed the style (I tested it with the 'alerts'), it didn't apply it on the page.

I spent alot on the investigation and later on I found out what happened with the help of my colleague. We tested with 'onmouseover' function and it works and we had an issue only with 'onclick'.

After checking the ViewSource, we realised that onmouseover function is added on the above the composite control and onclick function is added on the checkbox control itself. Generally that is correct. But the checkbox list hasn't got 'text' or attribute like that to change its style as far as I can see.

Thus, the final solution is to get the parentElement of the clicked checkBox and then change the style of that parentElement.

And voila! It works.