Unable to find control in gridview - c#

I want to find the control(hyperlink) in the gridview. Based on the value of the control I want to enable or disable the hyperlink.
I tried like this. But I am always getting null.
protected void gridResult_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink status = e.Row.FindControl("id") as HyperLink;
if ( status != null && status.Text == "AAAA" ) {
status.Enabled = false;
}
}
}
Please help.

Your "id" value is highly suspicious. My money is on the fact that you are supplying the wrong control name: FindControl("id!!!!!!!").
I would expect to see something like:
HyperLink status = e.Row.FindControl("hlStatus") as HyperLink;
If you are indeed supplying the correct control name (yuck), then it may be that your hyperlink control is nested too deep, in which case, you will need to 'crawl' your control hierarchy looking for it.

#dlev is absolutely correct, controls are often nested so you will need to create your own function of sorts to find what youre looking for, you could pass this function your control collection (e.Row.Controls()) and your id
private HyperLink FindControl(ControlCollection page, string myId)
{
foreach (Control c in page)
{
if ((HyperLink)c.ID == myId)
{
return (HyperLink)c;
}
if (c.HasControls())
{
FindControl(c.Controls, myId);
}
}
return null; //may need to exclude this line
}

Related

How to find all textboxes in a gridview row?

I have a GridView on a website, that have different controls in each row (eg.: textbox, label, dropdownlist). I need to find all textboxes and set the enabled property to false, so the user won't be able to edit them. I tried the code below, but it dosn't work, 'c' never recognised as a textbox, so it never changes the property.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (a)
{
foreach (Control c in e.Row.Controls)
{
if (c is TextBox)
{
((TextBox)(c)).Enabled = false;
}
}
}
}
I think you should try like this:
TextBox tb = e.Row.FindControl("textbox_name") as TextBox;
tb.Enabled = false;
Your textboxes must be nested within other controls, most likely cells inside the row. That is why you cannot find them just iterating through immediate children.
If you have a list of IDs of the text boxes, you should use FindControl:
((TextBox)e.Row.FindControl("TextBoxID")).Enabled = false;
Otherwise you will need to recursively find your controls of necessary type. See this thread for code sample.
One more option, if a is relatively easy to calculate, is to use in the markup directly, like so:
<asp:TextBox ... Enabled='<%# a %>' />
This depends a lot on the details of how a is derived. If it is a protected or public field of the page class, just the code above should work. If it is calculated based on row, you may need to turn it into protected method and pass params into it:
Enabled='<%# GetEnabled(Eval("Prop1"), Eval("Prop2")) %>'
And also want to put some updation.
There are different types of rows in gridview (header,footer,datarow,etc)
so for making little faster for the control find.
Try below (check the if condition)
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the TextBox control.
TextBox txtName = (e.Row.FindControl("txtName") as TextBox);
txtName.Enabled = false;
//or
TextBox txtName1 = (TextBox)e.Row.FindControl("txtName");
txtName1.Enabled = false;
}
}
You should search controls inside the cell instead of Row.
foreach (TableCell cell in e.Row.Cells)
{
foreach (Control c in cell.Controls)
{
if (c is TextBox)
{
((TextBox)(c)).Enabled = false;
}
}
}

How to disable Telerik radgrid hyperlink column when a specific condition is true

I have a Telerik Radgrid. I want to disable hyperlink columns on page load event when a specific condition is true.
I get role id from the database and on the basis of role id want to disable hyperlink columns on page load event.
my code is here
if(RoleId==3)
{
btnsave.Enabled= false;
foreach(griddataitem item in RagGrid1.Items)
{
HyperLink edit = (hyperlink)item["EditHyperLinkColumn"].Controls[0];
edit.Enabled = false;
}
}
when the page loads it gets the role id but did not go inside the foreach statement.
Please help.thanks in advance...
Where did you put your foreach loop in? In Page_Load method? This may not work because RadGrid has its own life cycle and events happen in particular sequence.
What you can do instead is to apply your condition in ItemDataBound event.
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
var item = (GridDataItem)e.Item;
var editlink = item.FindControl("EditHyperLinkColumn") as HyperLink;
if (editlink != null)
{
editlink.Enabled = false;
}
}
}
You need to get the items in the MasterTableView.
Also, verify the UniqueName of the Hyperlink Column. Is it actually "EditHyperLinkColumn"?
if(RoleID == 3)
{
btnsave.Enabled = false;
foreach(GridDataItem item in RadGrid1.MasterTableView.Items)
{
HyperLink edit = (HyperLink)item["EditHyperLinkColumn"].Controls[0];
edit.Enabled = false;
}
}

Getting the selected values in a checkbox list

I have set up the following method when the checkbox list is checked.
protected void chk1_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (ListItem list in chk1.Items)
{
if (list.Selected)
{
string name = list.Value.ToString();
}
}
}
I need to display the checked item from the checkbox list. However, for each iteration the selected attribute always comes false. It never satisfies the condition
if (list.Selected)
{
string name = list.Value.ToString();
}
How do I fix this?
Try something like this
var selectedListItems = chk1.Items.Cast<ListItem>().Where(x => x.Selected);
or in your case
var list = chk1.Items.Cast<ListItem>().Where(x => x.Selected);
now you will have a Collection that you can check / code against
also make sure that this code is being fired and or check if there is a PostBack
you can check this by checking if(!Is.PostBack){ }
My money is on you are re-binding the controls on every postback, instead do this:
if (!Page.IsPostBack)
{
// Only bind controls on initial page and let viewstate remember what the user did
}

SqlDatasource process records before display

I have a database with link urls and their respective display texts. I need to check if they are broken or not before their display string is shown in the gridview.
I am using SqlDatasource, is there a way to process records and use custom HTML markup to show them while using the SqlDataSource?
I am trying to use the OnSelected event of SqlDatasource but cant get how to use it.
I believe what you are trying to do is make sure that the hyperlink is valid before it gets put into the datagrid. To do this, you would need to subscribe to the RowDataBound event on your grid. From there, you can run code to evaluate your URL. Here is a quick example that would check to be sure that the URL field is not an empty string:
protected void selectedBookList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if ((e.Row != null) && (e.Row.RowType == DataControlRowType.DataRow))
{
string test = DataBinder.Eval(e.Row.DataItem, "URL").ToString();
if (test.Length == 0)
{
e.Row.Cells[3].Visible = false;
}
else
{
e.Row.Cells[3].Visible = true;
}
}
}
Instead of testing to be sure the length is equal to zero, you could check to see if the link is dead or not. Once you have evaluated it, you can hide the cell like I am doing here or you could modify the link, put in a generic link, etc.

Update label C#

When the page first load i have a label who has 0 or 1. Look at the code and you will se what i trying to do. But it don't work because the page allready loaded.
protected void rptBugStatus_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Label lblName = e.Item.FindControl("lblBugStatus") as Label;
if (lblName.Text == "1")
{
lblName.Text = lblName.Text + "Under arbete";
}
else if (lblName.Text == "0")
{
lblName.Text = "Fixad";
}
else { }
}
}
You really want to avoid this type of coding if at all possible. This will quickly grow into an unmaintainable web site.
Query the underlying data instead of GUI elements.
where you put your code? and be cautious e.Item.FindControl("lblBugStatus") as Label; may return null
it's just work fine to fine the control. But i figure out another way to get out the data i want. That i'am going to is fix the xml structur better.
You may have resolved this by now, but I think the problem with the code as you posted it is this:
Label lblName = e.Item.FindControl("lblBugStatus") as Label;
Because you are referencing a control in a repeater, the controls inside each repeater item are named dynamically based on their context. Most likely the name of the control is something like:
"rptBugStatus$repeaterItem0$lblBugStatus"
To find out the exact name, hard code a value, run the page in a browser, and look at the HTML output (via "View Source" in the browser menu). You should be able to scroll down and see your repeater (it will be rendered as a <table> tag), its items, and the controls living inside each item. The IDs/Names will be set and you can copy/paste them into your FindControl method.
Hope this helps,
Nate
Ok, I am taking the assumption you have set this label (assuming to be in the repeater, from your code) to have a value - I have tried databinding to something exactly the same, using the below code.
protected override void OnPreRender(EventArgs e)
{
base.OnLoad(e);
List<string> strList = new List<string>();
strList.Add("1");
rptBugStatus.DataSource = strList;
rptBugStatus.DataBind();
}
protected void rptBugStatus_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Label lblBugStatus = e.Item.FindControl("lblBugStatus") as Label;
// have added this just so we are actually setting the text property on the bug status
// - i have assumed you do this.
lblBugStatus.Text = e.Item.DataItem.ToString();
if (lblBugStatus.Text.Equals("1"))
{
lblBugStatus.Text = lblBugStatus.Text + "Under arbete";
}
else if (lblBugStatus.Text.Equals("0"))
{
lblBugStatus.Text = "Fixad";
}
}
}
With the aspx being
<asp:Repeater runat="server" ID="rptBugStatus" OnItemDataBound="rptBugStatus_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblBugStatus" runat="server"></asp:Label>
</ItemTemplate>
</asp:Repeater>
And I have no problems.
I get the below on the page.
1Under arbete
I think you are going to need to post more code if you have hidden any away from us :)
Tim

Categories