How can I create an object in .ascx? - asp.net

I've wrapped the asp:DropDown control so that I can create a lot of instances of it, all of which using the same additional functionality. I want to be able to create this object completely in the .ascx rather than using the code behind. I'm almost there, with the exception of the ListItems.
Here's what I have thus far, can anyone help me to figure out how to get the list items to populate?
<Control:DropDown ID="choice" runat="server" DropDownListLabel="Some Choice:"
QueryString="choice" SelectedIndex="0" ListItems='<%# new ListItemCollection(){
new ListItem("<no filter>", "-1"), new ListItem("Yes", "y"), new ListItem("No", "n")
} %>' />
Everything is working, with the exception of the ListItems, although the list items do work as expected from code behind. Any help on how I can get the ListItems accessor to call properly?
Thanks in advance,
Brett

You probably should have created your control to inherit from System.Web.UI.WebControls.DropDownList then override rendering and add properties that you want extra, this would allow you to something like the following:
<Control:DropDown id="mycontrol" runat="server" DropDownListLabel="Some Choice:" ..>
<asp:ListItem Text="<no filter" value="-1" />
...
</Control:DropDown>
Where DropDownListLabel is an added property. Of course in your case you'd add QueryString as a property as well

Related

using postbackurl to pass variables without referencing ctl00$MainContent

I'm hoping there's a cleaner way of doing this. My source page markup has some simple inputs and a submit button:
<asp:TextBox runat="server" ID="TBPostDateFrom" placeholder="From" />
<asp:TextBox runat="server" ID="TBPostDateTo" placeholder="Present" />
...
<asp:Button ID="BtnDetailedResults" PostBackUrl="~/Auth/ResultsDetail.aspx" runat="server" Text="View Detailed Results" />
On my target page, I'm trying to reference those controls and use them as datasource select parameters. So far the only way I've found to do that is to use the long asp generated names "ctl00$MainContent$TBPostDateFrom" and "ctl00$MainContent$TBPostDateTo":
SDSDetailedResults.SelectParameters.Add("PDFrom", Request.Form["ctl00$MainContent$TBPostDateFrom"]);
SDSDetailedResults.SelectParameters.Add("PDTo", Request.Form["ctl00$MainContent$TBPostDateTo"]);
Is there a way I can reference those controls without using the long ct100$...? Or a way to reference the controls directly? I'm guessing if sometime down the road I change my master page, or content controls, these references would get messed up.
I've tried adding using adding the ClientIDMode=Static to the inputs like:
<asp:TextBox runat="server" ID="TBPostDateFrom" placeholder="From" ClientIDMode="Static" />
But that appears to only change the ID. On my target page, I'm still unable to reference it without using the ct100$....
I've also tried using the Page.PreviousPage method, but the objects end up empty:
if (Page.PreviousPage != null)
{
//post date
TextBox PostDateFrom = (TextBox)Page.PreviousPage.FindControl("TBPostDateFrom");
TextBox PostDateTo = (TextBox)Page.PreviousPage.FindControl("TBPostDateTo");
//at this point both PostDateFrom and PostDateTo are empty, if I do this:
SDSDetailedResults.SelectParameters.Add("PostDateFrom", PostDateFrom.Text);
SDSDetailedResults.SelectParameters.Add("PostDateTo", PostDateTo.Text);
// I get an IIS error saying the object references dont' exist, or are null
}
}
Thanks in advance, any help or guidance is much appreciated!
For a search page, I would recommend using the QueryString to pass information to your later page, rather than trying to reference the controls from the previous page.
This will be especially useful if you want to use this functionality from different technologies. You won't have to worry about where the request came from.
SearchPage.aspx:
//Button Click:
var page = "ResultsDetail.aspx";
var url = String.Format("{0}?TBPostDateFrom={1}&TBPostDateTo={2}", page, TBPostDateFrom.Text, TBPostDateTo.Text);
Response.Redirect(url);
ResultDetails.aspx:
var from = DateTime.Parse(Request.QueryString["TBPostDateFrom"]);
var to = DateTime.Parse(Request.QueryString["TBPostDateTo"]);
//Do search based on parameters
For more information: MSDN - How to: Pass Values Between ASP.NET Web Pages

Data binding simple variable not working

This is the page code for the control:
<asp:TextBox id="someID" maxlength="10" columns="10" runat="server" Text="<%# work %>" />
This is how I set up and populate the variable before page is rendered, it is in the code behind, I have tried I think all the variations available for the variable declaration, e.g. public, shared, protected, etc.:
Public work As String
work = "987654321"
The textbox always comes up blank. referred to this ms kb page for how this work and it has a specific example.
However, it didn't explain anywhere if there is some special way of declaring the variables used in the binding or some special way to set the value of the variable, or is there something needed to allow the <%# syntax to work?
Binding doesn't happen automatically. You have to call DataBind() either from Page control or the text control. Try put it in Page_Load() method.

How to clear ONLY the databound items from a ASP.NET DropDownList and NOT any items added in Source?

The title pretty much asks the whole question - How can I clear ONLY the databound items from a ASP.NET DropDownList and NOT any items added in Source? If I have the following ddl:
<asp:DropDownList ID="ddl1" runat="server"
Width="300px" AppendDataBoundItems="true">
<asp:ListItem Text="(Please Select)" Value="0" />
</asp:DropDownList>
...and then call the following:
ddl1.Items.Clear()
The all the DDL ListItems go away and next time I rebind, the "(Please Select)" default option is gone.
Is there a more streamlined or elegant way to clear only the databound items but leave the "(Please Select)" default ListItem added in the source? I think I could call the Items.Clear() and pop that default item back in like ddl1.Items.Add(New ListItem("(Please Select)", "0")) as a new ListItem object, but I wondered if there was a better way to do this?
Thanks!
I found no other streamlined or better way than clearing the list and then adding the default item back into the collection like shown below:
ddl1.Items.Clear()
ddl1.Items.Add(New ListItem("(Please Select)", "0"))
How about this easy trick. The best advantage of using this trick is that if you make a custom dropdown list as well, It will work. It has been tested and worked perfectly.
while (ddl1.Items.Count != 1)
{
ddl1.Items.RemoveAt(1);
}
if the prompt is always the first element, then it will be the 0th item in the items collection. so you could iterate through the items deleting from 1 to N. there is a function to delete by index.

How to implement LayoutTemplate with a PlaceHolder

In my own server control, I would like to implement something similar to the ListView:
<asp:ListView runat="server">
<LayoutTemplate>
<asp:PlaceHolder runat="server" id="itemPlaceholder" />
</LayoutTemplate>
</asp:ListView>
I have created an ITemplate property, I can set the layout in the aspx page, and I am doing ITemplate.InstantiateIn(myControl).
But I can't figure out how to insert controls at the placeholder. I'm guessing it would be something like MyTemplate.FindControl("itemPlaceholder").Controls.Add(myControl). I tried casting to the type of my ITemplate, but I get the error:
Unable to cast object of type 'System.Web.UI.CompiledTemplateBuilder' to type 'MyNamespace.MyLayoutTemplate'
What am I missing?
Edit: I just found this: http://www.nikhilk.net/SingleInstanceTemplates.aspx Control developers can define templates to be single instance using metadata which causes the ID'd controls within the template contents to be promoted to the page level... The parser and code-generator together work behind the scenes to add member fields, and initialize them at the right time.. It seems to be only for user controls? I tried Page.FindControl() after doing this but it didn't find anything.
Ok, this was simply a matter of user error. I instantiated the ITemplate in a Panel, so obviously Page.FindControl() (which is not recursive) wouldn't work. Once I did Panel.FindControl(), everything worked.
In the past I have used this library with sucess
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

Inline code in ASp.Net menu item

Does anybody know if it is the way to set control's child attributes properties by inline code? I mean something like that
<asp:MenuItem Text="text" NavigateUrl='<%# GetItemURL("val") %>' ></asp:MenuItem>
CodeBehind
protected string GetItemURL(string tag)
{
if (string.IsNullOrEmpty(_pageUrl))
_pageUrl = UrlManager.CastQueryString(Request.Url.ToString());
return string.Format("{0}?item={1}", _pageUrl, tag);
}
Neither of approaches work, whatever you use <%#, <%= , Page.DataBind() etc, you get an obstacle.
It would be very ugly to set such properties in code-behind.
I hope the some method allowing to set such properties in code render blocks is available
thanks in advance.
Your binding syntax is correct. You just need to make sure something is binding the parent of the <asp:MenuItem> control. You can even just run this.Page.Databind(); if there isn't a good databinding context already.

Resources