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;
}
Related
Is there a simple property or method to check whether a row changed or column value has been changed in my grid view. I also want to get the index of modified/changed row
You can add it to the gridview like this
<asp:GridView Name="gridview1" OnRowUpdating="GridViewUpdateEventHandler" />
If I remember correctly there is an abundance of tutorials for gridviews and how to manipulate data.
No, there is no simple property for that. But...
Here is a method for that on MSDN
You'll have to modify it for your data and your control names to verify, but it's all there, straight from the keyboard of Microsoft.
protected bool IsRowModified(GridViewRow r)
{
int currentID;
string currentLastName;
string currentFirstName;
currentID = Convert.ToInt32(GridView1.DataKeys[r.RowIndex].Value);
currentLastName = ((TextBox)r.FindControl("LastNameTextBox")).Text;
currentFirstName = ((TextBox)r.FindControl("FirstNameTextBox")).Text;
System.Data.DataRow row =
originalDataTable.Select(String.Format("EmployeeID = {0}", currentID))[0];
if (!currentLastName.Equals(row["LastName"].ToString())) { return true; }
if (!currentFirstName.Equals(row["FirstName"].ToString())) { return true; }
return false;
}
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?
I'm iterating through a collection of asp:tablerows to be able to get or set the text in a textbox that is nested in the third cell of the row; I'm doing this by type rather than by ID because the cell ID's in that column aren't totally consistent--thus I can't really call FindControl() to achieve this. I've resorted to casting the third control in the TableRow to a TableCell and then Casting the first control in that cell to a TextBox. Not quite correct, as I'm getting an index out of range exception thrown. The problem mainly lies in the Controls.Count() property of the third cell, which comes to zero.
Not sure if there's a better way to access the textbox---should I resort to FindControl()?
The code:
foreach (TableRow row in tblProviders.Rows) {
string value = ((TextBox)((TableCell)row.Controls(2)).Controls(0)).Text;
...
}
My searches here only yielded use of FindControl(), so that may be the only way...
Thanks!
You could use Linq as follows:
var TextBoxes = tblProviders.Rows.OfType<TableRow>()
.SelectMany(row => row.Cells.OfType<TableCell>()
.SelectMany(cell => cell.Controls.OfType<TextBox>()));
TextBoxes would then be a collection of all the textboxes in tblProviders.Rows, which you could then itterate through and do what you like with.
A little bit of null checking wouldn't go amiss here.
You could try using this Recursive call:
foreach (TableRow row in tblProviders.Rows) {
var tb = FindControlRecursive(row, typeof(TextBox));
if (tb != null) {
string value = ((TextBox)tb).Text;
}
}
private Control FindControlRecursive(Control rootControl, Type controlType) {
if (rootControl.GetType() == controlType)
return rootControl; //Found it
foreach (Control controlToSearch in rootControl.Controls) {
Control controlToReturn = FindControlRecursive(controlToSearch, controlType);
if (controlToReturn != null) return controlToReturn;
}
return null;
}
I'm using a details view and a sqldatasource control to populate it. Every once in a while i get an error message because more than one row is returned. How can I have the data display in a gridview instead if more than one row is returned?
Databind to both and put this in the OnDataBound event or wherever appropriate in your code. (Obviously you'll need to tweak the code for the names of your objects)
if(myDataTable.Rows.Count > 1)
{
myGridView.Visible = true;
myDetailsView.Visible = false;
}
else
{
myGridView.Visible = false;
myDetailsView.Visible = true;
}
Ive no problems using Javascript to read the rows of a telerik radgrid component im using however I can seem to find anyway to access the row data server side when a postback occurs. Ive spent ages looking for solution but no luck.
Any pointers would be greatly appreciated.
Tony
You might want to look at the DataKeyValues property of the OwnerTableView object, which will let you access a collection of values that represent the fields in a given row. I use it during the EditCommand event handler, since a user of my site is directed to an edit page if they click on the link to edit a row in the grid, and I need to pass along certain info about the given row in the query string.
If this turns out to be what you need, you'll also need to define which fields should be made available through this property. To do that, look at the MasterTableView.DataKeyNames property in the property sheet for the grid. You basically specify a comma-delimited list of field names.
The server-side is the easy part:
GridItemCollection gridRows = TestGrid.Items;
foreach (GridDataItem data in gridRows)
{
ItemClass obj = (ItemClass)data.DataItem;
}
It's the client side part that I don't know! :[
private Int32 GetID()
{
foreach (Telerik.Web.UI.GridDataItem dataItem in radGrid.MasterTableView.Items)
{
if (dataItem.Selected == true)
{
Int32 ID = (Int32)dataItem.GetDataKeyValue("ID");
return ID;
}
}
throw new ArgumentNullException("Id Not found");
}
This is the one that works for me and uses the RadGrid.SelectedItems collection.
protected void LinkButton1_Click(object sender, EventArgs e)
{
List<Guid> OrderIdList = new List<Guid>();
foreach (GridDataItem OrderItem in this.RadGrid1.SelectedItems)
{
OrderIdList.Add(new Guid(OrderItem.GetDataKeyValue("OrderId").ToString()));
}
}
If you correctly created your controls in markup or page init for dynamic controls, then the RadGrid will properly restore state.
You can access the initial values that were loaded from the data source like this example below, provided you told the table view in question to keep the columns around in the data keys.
protected T GetInitialGridData<T>(GridDataItem item, string uniqueColumnName) {
item.ThrowIfNull("item");
uniqueColumnName.ThrowIfNullOrEmpty("uniqueColumnName");
return (T)item.OwnerTableView.DataKeyValues(gridItem.ItemIndex)(columnName);
}
If you are using a dynamic custom template column, and need to get to any values that may now be in their states, you can use:
protected string GetCustomTextBoxValue(GridDataItem item, string controlID) {
item.ThrowIfNull("item");
controlID.ThrowIfNullOrTrimmedEmpty("controlID");
return ((TextBox)item.FindControl(controlID)).Text;
}
private Int32 GetID()
{
foreach (Telerik.Web.UI.GridDataItem dataItem in radGrid.MasterTableView.Items)
{
if (dataItem.Selected == true)
{
// Int32 ID = (Int32)dataItem.GetDataKeyValue("ID");
Int32 ID =Convert.ToInt32(dataItem.GetDataKeyValue("ID"));
return ID;
}
}
}
//this will work