Enable hyperlink field in gridview while all other controls are disabled - asp.net

I have to disable all the controls on my gridview for business purposes.
Me.gvLineItems.Enabled=False
However, I need to enable one hyperlink field enabled so I tried this:
For Each Row As GridViewRow In Me.gvLineItems.Rows
Dim hrf As HyperLink
hrf = CType(Row.Cells(16).Controls(0), HyperLink)
hrf.Enabled = True
Next
I debug the code and it sets the hyperlink field enabled to true, but when I run the app the field is still disabled...
But If I get rid of the Me.gvLineItems.Enabled=False just comment that out and change my code to DISABLE the hyperlink field:
For Each Row As GridViewRow In Me.gvLineItems.Rows
Dim hrf As HyperLink
hrf = CType(Row.Cells(16).Controls(0), HyperLink)
hrf.Enabled = False
Next
This works fine...
But that is not what I need :(, just trying to reenable the link field...
Edit
I also tried this in the rowdatabound event:
If Me.gvLineItems.Enabled = False Then
For i As Integer = 0 To e.Row.Cells.Count - 1
If TypeOf (e.Row.Cells(i).Controls(0)) Is HyperLink Then
Dim h As HyperLink = CType(e.Row.Cells(i).Controls(0), HyperLink)
h.Enabled = True
Exit For
End If
Next
End If

I got it with this:
For i As Integer = 0 To e.Row.Cells.Count - 1
If TypeOf (e.Row.Cells(i).Controls(0)) Is HyperLink Then
Dim h As HyperLink = CType(e.Row.Cells(i).Controls(0), HyperLink)
h.Enabled = True
Exit For
Else
e.Row.Cells(i).Enabled = False
End If
Next

You'll need to use some type of recursive logic to loop through all the cells and disable the controls, with a condition to exclude HyperLink controls. By disabling the controls at the row level, the enabled state of the parent container (i.e. GridViewRow) will always override the enabled state of the control.
I would add some recursive logic in the RowDataBound event. Try something like this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DisableControls(e.Row);
}
private void DisableControls(WebControl parentCtrl)
{
if (parentCtrl.HasControls())
{
foreach (WebControl ctrl in parentCtrl.Controls)
{
ctrl.Enabled = ctrl is HyperLink;
DisableControls(ctrl);
}
}
else
{
parentCtrl.Enabled = parentCtrl is HyperLink;
}
}

Related

ASP.NET: TextBox.Text doesn't have updated value

I have an initialize function that loads data into my textbox NameTextBox, and then I add an "s" to the name. I then click the Save button that executes SaveButton_Click when debugging the value for NameTextBox.Text is still the original string (FirstName) and not (FirstNames). Why is this? Thanks.
Edit: Sorry here you go let me know if you need more...
Page_Load(sender, e)
Info = GetMyInfo()
Initialize()
Initialize()
NameTextBox.Text = Info.Name
SaveButton_Click(sender, e)
Dim command As SqlCommand
command = GetSQLCommand("StoredProcedure")
command.Parameters.AddWithValue("#Paramter", NameTextBox.Text)
ExecuteSQLCommand(command)
If the textbox is disabled it will not be persisted back to the codebehind, also if you set the initial value everytime (regardless of IsPostBack) you are essentially over writing what the value is when it gets to the Event handler (SaveButton_Click). Ex:
page_load() { NameTextBox.Text = "someValue";}
....
saveButton_Click() { string x = NameTextBox.Text;}
The above code will always have the text value of the textbox be "someValue". You would need to wrap it in an if(!IsPostBack) like so....
page_load() { if(!IsPostBack) {NameTextBox.Text = "someValue";}}
....
saveButton_Click() { string x = NameTextBox.Text;}

How do I send a value from a gridview control button field to another page?

protected void GridView3_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Drill")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow selectedRow = GridView3.Rows[index];
TableCell sitenamecell = selectedRow.Cells[1];
string Site = sitenamecell.Text;
Session["Location"] = Site;
lblSession.Text = Session["Location"].ToString();
Response.Redirect("DisplayForm.aspx");
I am assuming your other page is the page you are redirecting to?
If so just add whatever you want to the query string:
Response.Redirect("DisplayForm.aspx?yourParamNameHere=" + yourParamNameValue);
You can use the session but then you have to worry about the back button, forward buttons and multiple tabs (instances) messing up what is stored in the session. The safest method is to just make it part of the query string that your receiving page looks for.
You could do it as a GET variable:
GridViewRow selectedRow = GridView3.Rows[index];
TableCell sitenamecell = selectedRow.Cells[1];
string Site = sitenamecell.Text;
Session["Location"] = Site;
lblSession.Text = Session["Location"].ToString();
Response.Redirect("DisplayForm.aspx?site=" + Site);

How to hide columns in an ASP.NET GridView with auto-generated columns?

GridView1.Columns.Count is always zero even SqlDataSource1.DataBind();
But Grid is ok
I can do
for (int i = 0; i < GridView1.HeaderRow.Cells.Count;i++)
I rename request headers here
but
GridView1.Columns[i].Visible = false;
I can't use it because of GridView1.Columns.Count is 0.
So how can I hide them ?
Try putting the e.Row.Cells[0].Visible = false; inside the RowCreated event of your grid.
protected void bla_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false; // hides the first column
}
This way it auto-hides the whole column.
You don't have access to the generated columns through grid.Columns[i] in your gridview's DataBound event.
The Columns collection is only populated when AutoGenerateColumns=false, and you manually generate the columns yourself.
A nice work-around for this is to dynamically populate the Columns collection yourself, before setting the DataSource property and calling DataBind().
I have a function that manually adds the columns based on the contents of the DataTable that I want to display. Once I have done that (and then set the DataSource and called DataBind(), I can use the Columns collection and the Count value is correct, and I can turn the column visibility on and off as I initially wanted to.
static void AddColumnsToGridView(GridView gv, DataTable table)
{
foreach (DataColumn column in table.Columns)
{
BoundField field = new BoundField();
field.DataField = column.ColumnName;
field.HeaderText = column.ColumnName;
gv.Columns.Add(field);
}
}
Note: This solution only works if your GridView columns are known ahead of time.
It sounds like you're using a GridView with AutoGenerateColumns=true, which is the default. I recommend setting AutoGenerateColumns=false and adding the columns manually:
<asp:GridView runat="server" ID="MyGridView"
AutoGenerateColumns="false" DataSourceID="MySqlDataSource">
<Columns>
<asp:BoundField DataField="Column1" />
<asp:BoundField DataField="Column2" />
<asp:BoundField DataField="Column3" />
</Columns>
</asp:GridView>
And only include a BoundField for each field that you want to be displayed. This will give you the most flexibility in terms of how the data gets displayed.
I was having the same problem - need my GridView control's AutogenerateColumns to be 'true', due to it being bound by a SQL datasource, and thus I needed to hide some columns which must not be displayed in the GridView control.
The way to accomplish this is to add some code to your GridView's '_RowDataBound' event, such as this (let's assume your GridView's ID is = 'MyGridView'):
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[<index_of_cell>].Visible = false;
}
}
That'll do the trick just fine ;-)
You have to perform the GridView1.Columns[i].Visible = false; after the grid has been databound.
Try this to hide columns in an ASP.NET GridView with auto-generated columns, both RowDataBound/RowCreated work too.
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Or _
e.Row.RowType = DataControlRowType.Header Then // apply to datarow and header
e.Row.Cells(e.Row.Cells.Count - 1).Visible = False // last column
e.Row.Cells(0).Visible = False // first column
End If
End Sub
Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowCreated
If e.Row.RowType = DataControlRowType.DataRow Or _
e.Row.RowType = DataControlRowType.Header Then
e.Row.Cells(e.Row.Cells.Count - 1).Visible = False
e.Row.Cells(0).Visible = False
End If
End Sub
In the rowdatabound method for 2nd column
GridView gv = (sender as GridView);
gv.HeaderRow.Cells[2].Visible = false;
e.Row.Cells[2].Visible = false;
#nCdy:
index_of_cell should be replaced by an integer, corresponding to the index number of the cell that you wish to hide in the .Cells collection.
For example, suppose that your GridView presents the following columns:
CONTACT NAME | CONTACT NUMBER | CUSTOMERID | ADDRESS LINE 1 | POST CODE
And you want the CUSTOMERID column not to be displayed.
Since collections indexes are 0-based, your CUSTOMERID column's index is..........? That's right, 2!! Very good.
Now... guess what you should put in there, to replace 'index_of_cell'??
As said by others, RowDataBound or RowCreated event should work but if you want to avoid events declaration and put the whole code just below DataBind function call, you can do the following:
GridView1.DataBind()
If GridView1.Rows.Count > 0 Then
GridView1.HeaderRow.Cells(0).Visible = False
For i As Integer = 0 To GridView1.Rows.Count - 1
GridView1.Rows(i).Cells(0).Visible = False
Next
End If
I found Steve Hibbert's response to be very helpful. The problem the OP seemed to be describing is that of an AutoGeneratedColumns on a GridView.
In this instance you can set which columns will be "visible" and which will be hidden when you bind a data table in the code behind.
For example:
A Gridview is on the page as follows.
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" >
</asp:GridView>
And then in the code behind a PopulateGridView routine is called during the page load event.
protected void PopulateGridView()
{
DataTable dt = GetDataSource();
gv.DataSource = dt;
foreach (DataColumn col in dt.Columns)
{
BoundField field = new BoundField();
field.DataField = col.ColumnName;
field.HeaderText = col.ColumnName;
if (col.ColumnName.EndsWith("ID"))
{
field.Visible = false;
}
gv.Columns.Add(field);
}
gv.DataBind();
}
In the above the GridView AutoGenerateColumns is set to False and the codebehind is used to create the bound fields. One is obtaining the datasource as a datatable through one's own process which here I labeled GetDataSource(). Then one loops through the columns collection of the datatable. If the column name meets a given criteria, you can set the bound field visible property accordingly. Then you bind the data to the gridview. This is very similar to AutoGenerateColumns="True" but you get to have criteria for the columns. This approach is most useful when the criteria for hiding and un-hiding is based upon the column name.
Similar to accepted answer but allows use of ColumnNames and binds to RowDataBound().
Dictionary<string, int> _headerIndiciesForAbcGridView = null;
protected void abcGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (_headerIndiciesForAbcGridView == null) // builds once per http request
{
int index = 0;
_headerIndiciesForAbcGridView = ((Table)((GridView)sender).Controls[0]).Rows[0].Cells
.Cast<TableCell>()
.ToDictionary(c => c.Text, c => index++);
}
e.Row.Cells[_headerIndiciesForAbcGridView["theColumnName"]].Visible = false;
}
Not sure if it works with RowCreated().
Iterate through the GridView rows and make the cells of your target columns invisible. In this example I want to keeps columns 4-6 visible as is, so we skip those:
foreach (GridViewRow row in yourGridView.Rows)
{
for (int i = 0; i < rows.Cells.Count; i++)
{
switch (i)
{
case 4:
case 5:
case 6:
continue;
}
row.Cells[i].Visible = false;
};
};
Then you will need to remove the column headers separately (keep in mind that removing header cells changes the length of the GridView after each removal):
grdReportRole.HeaderRow.Cells.RemoveAt(0);

Store state of my checkbox list

How to store the state of my check box list tick boxes accross the page life cycle?
Here i have a unbound checkbox list control where values comes from xml file.
how to retain the state?
Moreover, when i click on Next button to the new page and comeback state is retained.
But when i click on the back button and come to the same page state is not retained
Protected Sub chkBx_SR_wu_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles chkBx_SR_wu.SelectedIndexChanged
Dim i As Integer
i = 0
Try
For i = 0 To chkBx_SR_wu.Items.Count - 1
If chkBx_SR_wu.Items(i).Selected Then
Select Case chkBx_SR_wu.Items(i).Value
Case "SR_MR"
chkbx_SR.Checked = True
Case "Sk_MR"
chkbx_SkRoom.Checked = True
Case "SC_SS"
chkbx_admin.Checked = True
Case "CS_MR"
chkbx_salesFloor.Checked = True
Case "TEAM_LEADER"
rb_tl.Enabled = True
chkbx_tlAdmin.Enabled = True
chkbx_tlJewellery.Enabled = True
chkbx_tlSalesFloor.Enabled = True
chkbx_tlSkRoom.Enabled = True
rb_tl.Items(0).Enabled = True
rb_tl.Items(1).Enabled = True
rb_tl.Items(2).Enabled = True
rb_tl.Items(3).Enabled = True
ReqiredFieldValidator1.Enabled = True
End Select
Else
Select Case chkBx_SR_wu.Items(i).Value
Case "SR_MR"
chkbx_SR.Enabled = False
chkbx_SR.Checked = False
Case "Sk_MR"
chkbx_SkRoom.Enabled = False
chkbx_SkRoom.Checked = False
Case "SC_SS"
chkbx_admin.Enabled = False
chkbx_admin.Checked = False
Case "CS_MR"
chkbx_salesFloor.Enabled = False
chkbx_salesFloor.Checked = False
Case "TEAM_LEADER"
chkbx_tlAdmin.Enabled = False
chkbx_tlAdmin.Checked = False
chkbx_tlJewellery.Enabled = False
chkbx_tlJewellery.Checked = False
chkbx_tlSalesFloor.Enabled = False
chkbx_tlSalesFloor.Checked = False
chkbx_tlSkRoom.Enabled = False
chkbx_tlSkRoom.Checked = False
rb_tl.Items(0).Enabled = False
rb_tl.Items(1).Enabled = False
rb_tl.Items(2).Enabled = False
rb_tl.Items(3).Enabled = False
ReqiredFieldValidator1.Enabled = False
End Select
End If
Next
Catch ex As Exception
End Try
End Sub"
My first guess, without seeing your code, is that you're binding the checkboxlist on Page_Load without checking to see if the page load is a postback. Do that and it should fix the problem.
You need to check where you are binding data to the checklist box. The problem isn't in the code you posted but where ever you are binding the code. Make sure you are checking for IsPostBack to be false or else every time your page loads, you will be rebinding your data and losing all your state. You should only bind once. Eg (in C#):
if (!IsPostBack)
{
BindMyDataToCheckBoxList();
}
Put a break point on where you binding the data, I bet everytime you doing anything like click a button or whatever, that binding code is getting hit which it probably shouldn't be.
There's no guaranteed method of having the values retained if they visit the page again but not if they use the back button. You could try setting the page headers so that the page is not cached as a precaution against the user seeing invalid data.
In the Page_Init stage of the page lifecycle, you can populate your checkbox list with the values from your XML file, and then in the Page_Load stage, check that the page isn't be posted back and select the checkboxes accordingly using the values in the session.
Eg. in C# -
protected void Page_Init(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Populate checkbox list from XML
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<string> list = Session["MyList"] as List<string>;
if (list != null)
{
foreach (int val in list)
{
ListItem chk = myCheckBoxList.Item.FindByValue(val);
if (chk != null)
chk.Checked = true;
}
}
}
}
protected void SaveButton_Click(object sender, EventArgs e)
{
List<string> list = new List<string>();
foreach (ListItem li in myCheckBoxList.Items)
{
if (li.Checked)
{
list.Add(li.Value);
}
}
Session["MyList"] = list;
}
This code hasn't been tested, but could be used a starting point. You can convert the code to VB.NET using a code converter, such as the one from Telerik.
You can retain state of checkboxes across/on pages either by:
Cookie
Sessions
ViewState
or Save it in
Database.
I would recommend Sessions as it is quite trivial to use, and does not require them to have cookies enabled.
A simple tutorial on sessions can be found here. That is a c# version.
Here is a vb.net example (but not from MSDN)

get selected row index of dynamic dropdown list selection

I know the question is a little choppy and perhaps misleading,but I have a gridview with dropdownlists on the rows. I created an AddHandler and a Delegate for the SelectedIndexChanged and it gets to the sub. Here is the code for that:
AddHandler ddlmgr.SelectedIndexChanged, AddressOf ddlmgr_SelectedIndexChanged
Public Delegate Sub DropDownList_SelectedIndexChanged(ByVal sender As Object, ByVal e As DropDownList_SelectedIndexChanged)
Protected Sub ddlmgr_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
End Sub
How can i get the row's Id if GridView_RowCommand is not called?
You will need to do a bit of the legwork as I cant provide 100% specifics without writing out the code and testing it on my own here, which I am unable to do at present, but the code should go along these lines.
within the ddlmgr_SelectedIndexChaged,
cast your sender to a DropDownList
access the part property of the dropdownlist.
Check it is is a GridItem (or repeateritem or whichever, you get the idea)
If so, get the items itemindex. If not access its parent property.
Continue until you find your Row object.
Hopefully this helps. If not, perhaps someone with a bit more liberal access can chime in
DropDownList ddl = (DropDownList)sender;
Control p = ddl.Parent;
//you are going to loop because the immediate
//parent may not be the repeater item but instead a
//container control of some kind (say a template)
while (p.GetType() != typeof(RepeaterItem))
{
p = p.Parent;
if (p == null) return; //we have reached the top of the control tree
}
RepeaterItem ri = (RepeaterItem)p;
int index = ri.ItemIndex
return index;
Great work
Works absolutely fine for me
DropDownList ddl = (DropDownList)sender;
Control p = ddl.Parent;
//you are going to loop because the immediate
//parent may not be the repeater item but instead a
//container control of some kind (say a template)
while (p.GetType() != typeof(RepeaterItem))
{
p = p.Parent;
if (p == null)
return; //we have reached the top of the control tree
}
RepeaterItem ri = (RepeaterItem)p;
int index = ri.ItemIndexreturn index;
DropDownList ddltxt = (DropDownList)sender;
string temp2 = ddltxt.SelectedItem.Text;
string temp3 = ddltxt.SelectedItem.Value;
string temp = ddltxt.ID.ToString();
int strlength = temp.Length;
string strLastchar = temp.Substring(strlength - 1, 1);
int intlastchar = int.Parse(strLastchar.ToString());
string commonpart = temp.Substring(0, strlength - 1);
if (intlastchar == 1)
{
string targetdropdownid = commonpart + "2";
DropDownList targetlist = (DropDownList)TableRow11.FindControl(targetdropdownid);
using (conn = new SqlConnection(ConnectionString))

Resources