i have an asp repeater control , i bind data source from page load , if there is data , everything works well , but when i have no data to display i want to access footer template to show label : "No available data "
i try with this code :
Label lblTotal = (Label)repeaterAccessFooterControl.Controls[repeaterAccessFooterControl.Controls.Count - 1].FindControl("lblTotal");
but repeaterAccessFooterControl.Controls.Count always = 0 ..
how can i access footer control from page load,
i think that, in page load, repeater doesn't properly rendered yet .. so that it equals 0
how can i achieve that ??
Make sure that when you have no data to show, that you bind an empty collection to your repeater and not null value. Then you can your control with FindControlRecursive, like this:
var lblTotal = FindControlRecursive(<<your_repater_control>>, "lblTotal") as Label;
and here is the definition of FindControlRecursive
public Control FindControlRecursive(Control root, string id)
{
return root.ID == id ? root : (from Control c in root.Controls select FindControlRecursive(c, id)).FirstOrDefault(t => t != null);
}
Regards,
Uros
Why not switch to a ListView, then you can use the EmptyDataTemplate?
Related
Edit (more brief):
I have a control "configuration" with a tree view on the left and a list of panels on the right to which i add my controls. These elements are placed inside a table and surrounded by an ajax panel.
Let's say i have a tree node cars with two elements car1 and car2. When i click an item i save the ID and Type of the selected tree node inside hidden fields to be able to load the right user control on Page_Init
protected void Page_Init(object sender, EventArgs e)
{
var type = this.Request.Form["ctl00$MainContent$ctl00$typeId"];
var id = this.Request.Form["ctl00$MainContent$ctl00$entityId"];
if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(id))
{
this.LoadUserControl(type, id);
}
}
private void LoadUserControl(string type, string id)
{
if (Convert.ToInt32(type) != 0)
{
switch (Convert.ToInt32(type))
{
case (int)SkTopics.Product:
this.AddUserControl("../Modules/Product.ascx", this.Product, type, id);
break;
}
}
}
private void AddUserControl(string controlName, Panel panel, string type, string id)
{
// Init new user cotntrol
control = (BaseControl)this.LoadControl(controlName);
control.LoadEntityItem(Convert.ToInt32(id));
// Setting the user control ID
var replace = controlName.Replace("../Modules/", string.Empty);
string userControlId = replace.Split('.')[0] + id;
var targetControl = panel.FindControl(userControlId);
if (object.Equals(targetControl, null))
{
control.ID = userControlId;
control.DataBind();
panel.Controls.Add(control);
}
}
On LoadEntityItem the data for this car are collected from the database and the values are set as Text of textboxes. When i now switch to the second car, the new values are displayed.
Problem: I change the values inside the textboxes and press the save button to call my save method of the user control. From now on, when i switch to the car 1 again, the values for car 2 are still displayed, although the data for car1 are filled. tO see the data for car1 i have to switch to a complete different type of control and then back to the car1.
Another problem is, that i have a binary image inside the user control which Data i fill on init. When i swith to the the next car, where there i no image configured, i set the image data to null, but the image from the previous car i show. Onyl if i set a different image data the new image is displayed.
There is something else i noticed:
Inside the user control i call a javascript funtion but this one is only called on clicking the the save button. It seems that there is a different between the switch of the tree node and the save button click ?
ScriptManager.RegisterStartupScript(this, this.GetType(), "InitScrewPointsForDragging", "InitScrewPointsForDragging();", true);
I hope this was more brief than before.
It seems that the reason for the issue is some improper viewstate handling and after I disable the view state it is working correctly at my side. Here is the code that I updated to have it work at my side:
this.control.EnableViewState = false;
this.control.ID = userControlId;
I'm using a stored procedure in a sql database as the data source for a SqlDataSourceControl on my .aspx page. I'm then using the SqlDataSourceControl as the data source for a gridview on my page. Paging is set to true on the gridview. What i would like to do is set the text of a label to the total number of rows in the gridview. I can use this code
'labelRowCount.Text = GridView2.Rows.Count & " layers found"
to return the number of results per page, but it doesn't give me the total. I've looked in several places and haven't been successful in finding a solution.
You should use the underlying datasource that the gridview is bound to (grid.DataSource). For instance if you have bound the grid to a datatable then just cast the grids datasource into the datatable and the use the rows.count property to get the total record count. Another alternative would be to get a reference to the the grids datasource object before you set it to the grid so you can get the record count directly.
So for example (assuming you are bound to a DataTable)
int count = ((DataTable)grid.DataSource).Rows.Count;
Enjoy!
Put an event handler on "selected" for the SQL DataSource. That event handler has an argument of type SqlDataSourceStatusEventArgs. In there AffectedRows is the row count of the entire data set (not just that shown on the current page). So catch that and write it out to your label:
protected void SqlDataSource_Selected(object sender,SqlDataSourceStatusEventArgs e)
{
if (e.Exception != null)
{
// do something useful, then...
e.ExceptionHandled = true;
}
else
labelRowCount.Text = String.Format("{0} layers found", e.AffectedRows);
}
GridView2.Rows saves only the rows that are visible, so when page-size is 5 you get only 5 records. As Doug suggested you have to set the labelRowCount.Text ondatabound and not on every postback, because on postback - when the datasource is not binded again - the datasource will be nothing. So a good place could be where you bind the grid to the datasource.
The current form is here. It is not complete, and only a couple options will work.
Select "Image CD" and then any resolution and click "Add to Order." The order will be recorded on the server-side, but on the client-side I need to reset the product drop-down to "{select}" so that the user will know that they need to select another product. This is consistant with the idea that the sub-selections disappear.
I don't know whether I should be using ASP postback or standard form submittal, and most of the fields need to be reset when the user adds an item to the order.
I'd use Response.Redirect(Request.RawUrl) method to reset the form data from the server side.
A little explanation: this is PRG design pattern
Used to help avoid certain duplicate
form submissions and allow user agents
to behave more intuitively with
bookmarks and the refresh button.
A workaround for this question:
necessary data may be stored in Session for example. This means we getting the data with the first POST, putting it to the storage, performing redirect and getting it back.
In the pageload event on the form, you need to add something simalar to this:
if (IsPostBack)
{
//Proccess the order here
ProductOption.SelectedIndex = 0;
}
That will allow you to process the order, but then start over the order form.
The simplest means would be a recursive function that forks on the type of control
private void ResetControls( Control control )
{
if ( control == null)
return;
var textbox = control As TextBox;
if ( textbox != null )
textbox.Text = string.Empty;
var dropdownlist = control as DropDownList;
if ( dropdownlist != null )
dropdownlist.SelectedIndex = 0; // or -1
...
foreach( var childControl in controlControls )
ResetControls( childControl );
}
You would this call this function in your Load event by passing this. (This is presuming you want to reset more than a single control or small list of controls).
I have a listView control which is bound to an object datasource. In the ListView1_ItemDataBound event, I am generating some dynamic controls. I do this because depending on a particular column value, i might need to generate textbox, radio button, check box etc.
Some code here:
ListViewDataItem item = (ListViewDataItem)e.Item;
typez = Convert.ToInt32(DataBinder.Eval(item.DataItem,"Type").ToString());
if (typez == 1) //1 means generate radibutton
{
string[] options = DataBinder.Eval(item.DataItem, "QuestionDetail").ToString().Split(new string[] { delimiter }, StringSplitOptions.None);
questionID = Convert.ToInt32(DataBinder.Eval(item.DataItem, "Question_ID").ToString());
int optionCount = 1;
RadioButtonList rbl = new RadioButtonList();
//set ID for the radiobtnList to the questionid no.
rbl.ID = "mcq_" + questionID;
foreach (string s in options)
{
//adds the MCQ options to list item
ListItem li = new ListItem(Util.GetAlphabet(optionCount).ToUpper() + ". " + s, Util.GetAlphabet(optionCount).ToUpper(), true);
rbl.Items.Add(li);
optionCount++;
}
//PlaceHolder PlaceHolder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
PlaceHolder1.Controls.Add(rbl);
I have DataPager also. When I go to the next page I want to somehow capture the user response in the previous page. Otherwise, all the user response is lost. I tried using ListView1_PagePropertiesChanging event. But here I somehow do not seem to get the dynamic controls in the page.
I need to get the radio button selected value so that I can save it or put in some session variable so that when user comes back to this page he can see his previuos values.
Could someone please suggest some insight on what I am doing wrong.
Problem is that you have to create controls in OnInit, then ViewState persister can do it's job. If you do it after OnInit, in ItemDataBound, when Postback is triggered, controls doesn't exists and their's viewstate isn't deserialized.
To access values of radio buttons and get selected one, you have to look at Request.Form dictionary and find it.
Using ASP.NET 3.5 ListView control.
I would like to capture the value of my table id from the currently edited row of a ListView.
A ItemEditing event has been added to the ListView.
The only value available in this event is e.NewItemIndex.
This returns 0 if the first row of the current page of the ListView is being edited.
How do I convert this 0 into the actual table id (label control value)?
I have tried:
table_id = Convert.ToString(ListView1.Items[e.NewEditIndex].FindControl("table_idLabel1"));
Can you use the DataKeyNames property instead of a label? Set the property to the name of the database field that is the key for the table, then do something like this:
table_id = ListView1.DataKeys[e.NewEditIndex].Value.ToString();
Are you sure table_idLabel1 is the correct id?
Also, you may need to look recursively as in Chris's answer. Plus, it looks like your casting the control to a string. You probably want the ID property and not the control itself.
Use FindControlRecursive (from Recursive Page.FindControl). The problem with FindControl is that it only search one layer deep.
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}