Standardize the gridView pager template - asp.net

I have a custom pager template on one gridview that the client now wants applied to several other gridviews within the same site. It seems like extending the GridView object makes the most sense, but I'm not clear on how to create the pager template dynamically.
Any recommendations on how to accomplish this?

Does this work:
gridview.PagerTemplate = Page.LoadTemplate("CustomPager.ascx");
http://msdn.microsoft.com/en-us/library/6d5z5yty(VS.80).aspx
UPDATE
For extension:
public class CustomGridView : GridView {
public override void OnInit(EventArgs e) {
base.OnInit(e);
this.PagerTemplate = Page.LoadTemplate("CustomPager.ascx");
}
}

I'm not sure why this article didn't turn up until now, but I found a nice tutorial on DotNetSlackers that got me going in the right direction.
http://dotnetslackers.com/articles/gridview/Custom-GridView-with-Paging-and-Filtering.aspx
Unfortunately, I did have to create the pager controls dynamically. If anyone knows a better way, I'm still all ears as I would much rather write HTML as is done in the PagerTemplate.

Related

dynamically change body id in masterpage in asp.net 2.0

Greetings,
I'm pretty new to the asp.net platform, and am having trouble doing the simplest of things.
As my title suggests, I'm wanting to dynamically change the body id on my master page in order to change the background and formatting of the page depending on what section of the website you're on. I have an idea on how to implement it, I'm just not versed enough with C# and asp.net to know how to code it.
I realize that people may say to utilize different methods than changing the body ID tag, but in my case with the liquid design of my website (full screen viewing), changing the body ID dynamically would be the easiest and most modular way for the way I have things laid out.
If anyone could shed some light, it would be much appreciated. As I'm a newbie and am still having trouble calling classes and passing information between pages, being as specific as possible would be also very much appreciated.
Thanks in advance.
Put an id for the body tag in your master page (I've named it body here)
<body runat="server" id="body">
Set the body id in your MasterPage class > Page_Load event (I added the following bit in Site.master.cs to set the body id to the content page's class name)
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
// for page specific styling
body.ID = ContentPlaceHolder.Page.GetType().BaseType.Name;
}
}

CommandEventArgs null value in OnCommand event handler for a Custom WebControl implementing IButtonControl

I am very sorry for the long title but I really didn't know how to be more self explaining than this.
The problem I have is this:
I designed and developed a WebControl which consists in a simple set of elements that, combined togheter in the simplest way, defines a custom button. This control is the one I would like to use in my web application instead of Button and LinkButton control (reasons mainly rely on graphic and visual functionalities).
In order to let the webcontrol behave like a button, it also implements the IButtonControl interface so that all elements needed by the framework in order to handle events and similar stuff are well provided.
Well, this button I called BoxButton works fine everytime it is used, instead for one thing.
Sorry for the long prelude, now we can go straight to the real problem:
In a page I have a ListView and in the listview I have the InsertItemTemplate enabled.
Well this insertitemtemplate works fine when the OnItemInsert is fired by pressing a button inside the template (a button, an ordinary button control).
Well, I sure wanted to place my BoxButton in place of the ordinary one. When I do this I have a problem.
The handler function is this:
protected void Insert_BoxButton_Command(object sender, CommandEventArgs e) {
if (e.CommandName == "Insert") {
// Do something
}
}
Typically, the e object is able to give information to the developer in order to locate all data to be inserted. These data are available when I use a normal button, but when using a BoxButton it is null!
Well, you could tell me that, when I defined my BoxButton implementing the IButtonControl interfaces, I had to manage with both the two events in the interface (dealing woth button pressure: Click and Command) and manage with the problem of providing CommandEventArgs. But how to do this?
Is there a solution to my problem? How can I manage eventargs? I sense that probably this is a very low programming issue... maybe there is much to do.
Thanks in advance for your help.
Andry

How to change the Master Page dynamically

I want to assign one master page dynamically for a pure aspx file, Anybody can tell me, how to do this?
You can override OnPreInit in your default.aspx.cs and set the master page based on some value in your querystring. Something like this:
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (Request.QueryString["Master"] == "Simple")
MasterPageFile = "~/Masterpages/Simple.Master";
}
EDIT: the cause of your error message might be covered by this question.
I Left the ContentPlaceholder to add on it.. Actually , I tried to assign master page without using ContentPlaceHolder.. Now, I realised that, atleast one ContentPlaceholder should be there temporarily, even though we will change the master page dynamically...

Child Control Initialization in Custom Composite in ASP.NET

Part of the series of controls I am working on obviously involves me lumping some of them together in to composites. I am rapidly starting to learn that this takes consideration (this is all new to me!) :)
I basically have a StyledWindow control, which is essentially a glorified Panel with ability to do other bits (like add borders etc).
Here is the code that instantiates the child controls within it. Up till this point it seems to have been working correctly with mundane static controls:
protected override void CreateChildControls()
{
_panel = new Panel();
if (_editable != null)
_editable.InstantiateIn(_panel);
_regions = new List<IAttributeAccessor>();
_regions.Add(_panel);
}
The problems came today when I tried nesting a more complex control within it. This control uses a reference to the page since it injects JavaScript in to make it a bit more snappy and responsive (the RegisterClientScriptBlock is the only reason I need the page ref).
Now, this was causing "object null" errors, but I localized this down to the render method, which was of course trying to call the method against the [null] Page object.
What's confusing me is that the control works fine as a standalone, but when placed in the StyledWindow it all goes horribly wrong!
So, it looks like I am missing something in either my StyledWindow or ChildControl. Any ideas?
Update
As Brad Wilson quite rightly pointed out, you do not see the controls being added to the Controls collection. This is what the _panel is for, this was there to handle that for me, basically then override Controls (I got this from a guide somewhere):
Panel _panel; // Sub-Control to store the "Content".
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _panel.Controls;
}
}
I hope that helps clarify things. Apologies.
Update Following Longhorn213's Answer
Right, I have been doing some playing with the control, placing one within the composite, and one outside. I then got the status of Page at event major event in the control Lifecycle and rendered it to the page.
The standalone is working fine and the page is inited as expected. However, the one nested in the Composite is different. It's OnLoad event is not being fired at all! So I am guessing Brad is probably right in that I am not setting up the control hierarchy correctly, can anyone offer some advice as to what I am missing? Is the Panel method not enough? (well, it obviously isn't is it?!) :D
Thanks for your help guys, appreciated :)
I don't see you adding your controls to the Controls collection anywhere, which would explain why they can't access the Page (since they've never been officially placed on the page).
I have always put the JavaScript calls on the OnLoad Function. Such as below.
protected override void OnLoad(EventArgs e)
{
// Do something to get the script
string script = GetScript();
this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "SomeJavaScriptName", script);
// Could also use this function to determine if the script has been register. i.e. more than 1 of the controls exists
this.Page.ClientScript.IsClientScriptBlockRegistered("SomeJavaScriptName");
base.OnLoad(e);
}
If you still want to do the render, then you can just write the script in the response. Which is what the RegisterScriptBlock does, it just puts the script inline on the page.
Solved!
Right, I was determined to get this cracked today! Here were my thoughts:
I thought the use of Panel was a bit of a hack, so I should remove it and find out how it is really done.
I didn't want to have to do something like MyCtl.Controls[0].Controls to access the controls added to the composite.
I wanted the damn thing to work!
So, I got searching and hit MSDN, this artcle was REALLY helpful (i.e. like almost copy 'n' paste, and explained well - something MSDN is traditionally bad at). Nice!
So, I ripped out the use of Panel and pretty much followed the artcle and took it as gospel, making notes as I went.
Here's what I have now:
I learned I was using the wrong term. I should have been calling it a Templated Control. While templated controls are technically composites, there is a distinct difference. Templated controls can define the interface for items that are added to them.
Templated controls are very powerful and actually pretty quick and easy to set up once you get your head round them!
I will play some more with the designer support to ensure I fully understand it all, then get a blog post up :)
A "Template" control is used to specify the interface for templated data.
For example, here is the ASPX markup for a templated control:
<cc1:TemplatedControl ID="MyCtl" runat="server">
<Template>
<!-- Templated Content Goes Here -->
</Template>
</cc1:TemplatedControl>
Heres the Code I Have Now
public class DummyWebControl : WebControl
{
// Acts as the surrogate for the templated controls.
// This is essentially the "interface" for the templated data.
}
In TemplateControl.cs...
ITemplate _template;
// Surrogate to hold the controls instantiated from
// within the template.
DummyWebControl _owner;
protected override void CreateChildControls()
{
// Note we are calling base.Controls here
// (you will see why in a min).
base.Controls.Clear();
_owner = new DummyWebControl();
// Load the Template Content
ITemplate template = _template;
if (template == null)
template = new StyledWindowDefaultTemplate();
template.InstantiateIn(_owner);
base.Controls.Add(_owner);
ChildControlsCreated = true;
}
Then, to provide easy access to the Controls of the [Surrogate] Object:
(this is why we needed to clear/add to the base.Controls)
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _owner.Controls;
}
}
And that is pretty much it, easy when you know how! :)
Next: Design Time Region Support!
Right, I got playing and I figured that there was something wrong with my control instantiation, since Longhorn was right, I should be able to create script references at OnLoad (and I couldn't), and Brad was right in that I need to ensure my Controls hierarchy was maintained by adding to the Controls collection of the composite.
So, I had two things here:
I had overriden the Controls property accessor for the composite to return this Panel's Controls collection since I dont want to have to go ctl.Controls[0].Controls[0] to get to the actual control I want. I have removed this, but I need to get this sorted.
I had not added the Panel to the Controls collection, I have now done this.
So, it now works, however, how do I get the Controls property for the composite to return the items in the Panel, rather than the Panel itself?

Creating a UserControl Programmatically within a repeater?

I have a repeater that is bound to some data.
I bind to the ItemDataBound event, and I am attempting to programmatically create a UserControl:
In a nutshell:
void rptrTaskList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
CCTask task = (CCTask)e.Item.DataItem;
if (task is ExecTask)
{
ExecTaskControl foo = new ExecTaskControl();
e.Item.Controls.Add(foo);
}
}
The problem is that while the binding works, the user control is not rendered to the main page.
Eh, figured out one way to do it:
ExecTaskControl foo = (ExecTaskControl)LoadControl("tasks\\ExecTaskControl.ascx");
It seems silly to have a file depedancy like that, but maybe thats how UserControls must be done.
You could consider inverting the problem. That is add the control to the repeaters definition and the remove it if it is not needed. Not knowing the details of your app this might be a tremendous waste of time but it might just work out in the end.
If you are going to do it from a place where you don't have an instance of a page then you need to go one step further (e.g. from a webservice to return html or from a task rendering emails)
var myPage = new System.Web.UI.Page();
var myControl = (Controls.MemberRating)myPage.LoadControl("~/Controls/MemberRating.ascx");
I found this technique on Scott Guithrie's site so I assume it's the legit way to do it in .NET
I think that #Craig is on the right track depending on the details of the problem you are solving. Add it to the repeater and remove it or set Visible="false" to hide it where needed. Viewstate gets tricky with dynamically created controls/user controls, so google that or check here if you must add dynamically. The article referenced also shows an alternative way to load dynamically:
Control ctrl=this.LoadControl(Request.ApplicationPath +"/Controls/" +ControlName);

Resources