I am trying to hide a column in grid based on user role type
this is my c# code
protected void gvBudget_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (user == "1")
{
ImageButton imgBtn = (ImageButton)e.Row.FindControl("imgDelete");
imgBtn.Visible = false;
}
}
}
catch (Exception ex)
{
log.Info("Error in gvBudget_RowDataBound() " + ex.ToString());
}
}
this is the html page
<asp:TemplateField HeaderText="Delete" HeaderStyle-CssClass="grid_header_text">
<ItemTemplate>
<asp:ImageButton ID="imgDelete" runat="server" CommandName="DEL" ImageUrl="~/Image/delete.gif"
OnClientClick="if(confirm('Budget List Summary \n\n Selected record will be deleted please confirm')==false){event.returnValue=false;return false;}else{return true;}" TabIndex="18" ToolTip="Delete" />
</ItemTemplate>
<HeaderStyle CssClass="grid_header_text"></HeaderStyle>
</asp:TemplateField>
i am able to hide the button, but unable to hide the row header or the column.
Based on your error message that you're logging, I am assuming that you have a GridView. If that is the case, couldn't something like this work?
gvBudget.Columns[0].Visible = false;
Ok, the problem is if we JUST hide the control, the column still renders. The key Rosetta stone here was that in fact your column control WAS hiding.
Say we have this:
And my code to hide the link button is say is this:
Dim lb As LinkButton = gv.FindControl("btnLNK")
lb.Visible = False
Then we get this:
So it DOES hide the control "in side" the column, but not the whole column.
So, you have to hide the cell, say like this:
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(4).Visible = False
End If
But note how his ONLY hide the data, not the header.
So we have to hide both header, and the data, say like this:
If e.Row.RowType = DataControlRowType.DataRow Or
e.Row.RowType = DataControlRowType.Header Then
e.Row.Cells(4).Visible = False
End If
And we get this:
Related
I am still a novice with asp.net, so I'm sure there are better ways to do some of this...
I want to allow a user to enter a date, and then execute an SQL query against a database to return all records matching that date. I want to display those records, and allow the user to select one for additional processing. It seemed like the DataGrid with a column of Pushbuttons was a good choice. In fact, I've done this before, but it those cases there was no user interaction involved. The page just ran a fixed SQL query. With what I'm doing now, the data is displayed as I want, but the Pushbuttons aren't working...the ItemCommand event doesn't fire.
I've read a lot of threads about the ItemCommand event not firing, but I still can't get this to work. My understanding is that I need to bind the DataGrid while not in a Postback, and I think my code does that. When I debug the Page_Load event, I can see that the code inside if (!IsPostBack){} is running, and the session variables have the expected data.
On the page that hosts the DataGrid, I have a 'Find' button that executes a SQL query against a database. The query uses a date entered into the textbox that is on that page. In the 'Find' button click event, I store the results of the query (a DataTable) in a session variable, then do a Redirect to re-load the page.
Once the page reloads, the session variables contain my expected data and the data is displayed in the DataGrid, along with the Pushbuttons. When I click any of the buttons in the DataGrid, the contents of the DataGrid disappear and the ItemCommand event does not fire.
Here's the definition of the DataGrid (updated to include the button):
<asp:Panel runat="server" ID="pnlSelect" HorizontalAlign="Left" Visible="true" style="margin-top:10px" >
Please select a participant.
<asp:DataGrid runat="server" ID="grdItems" AutoGenerateColumns="true" BorderColor="black" BorderWidth="1" CellPadding="3" style="margin-left:2px; margin-top:6px" OnItemCommand="grdSelect_ItemCommand" >
<Columns>
<asp:ButtonColumn HeaderStyle-HorizontalAlign="Center" ButtonType="PushButton" Text="Select" HeaderText="Select" CommandName="Select" >
<ItemStyle Width="60px" HorizontalAlign="Center"/>
</asp:ButtonColumn>
</Columns>
</asp:DataGrid>
</asp:Panel>
Here's the Page Load code (unneeded code-behind stuff is commented out):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["y"] != null)
{
txtFind.Text = Session["x"].ToString();
DataTable table = Session["y"] as DataTable;
Session.Remove("x");
Session.Remove("y");
if (table != null)
{
/*
ButtonColumn buttonColumn = new ButtonColumn
{
HeaderText = "Select",
Text = "Select",
CommandName = "Select",
ButtonType = ButtonColumnType.PushButton,
};
grdItems.Columns.Add(buttonColumn);
foreach (DataColumn c in table.Columns)
{
BoundColumn column = new BoundColumn
{
HeaderText = c.Caption,
DataField = c.Caption,
ReadOnly = true
};
grdItems.Columns.Add(column);
}
*/
grdItems.DataSource = table;
grdItems.DataBind();
}
}
}
}
Here's the relevant 'Find' button event code. I can't post the details of the sql query text, but that part does work and the DataTable does contain the expected data:
DataTable table = DatabaseHelper.FindBySQL(sqlText);
if (table != null && table.Rows.Count > 0)
{
Session["x"] = searchtext;
Session["y"] = table;
Response.Redirect(Request.RawUrl, true);
}
And this the ItemCommand event. I place a breakpoint on the first line, and the debugger never hits it.
protected void grdItems_ItemCommand(object source, DataGridCommandEventArgs e)
{
string item = "";
switch (e.CommandName.ToLower())
{
case "select":
item = e.Item.Cells[1].Text.Trim();
//todo: handle the selected data
break;
}
}
Thanks for any thoughts.
Don
I am developing a Web Form, where I show Gridview with data. One of the column consists of CheckBox. How can I update data in particular row.
so my question is:
How to unidentified particular row and send an sql request with UPDATE when user Check or Uncheck the CheckBox?
Update:
Here is my code that i have. It doesn't update value of CheckBox.
namespace:
public partial class Call_Bills : System.Web.UI.Page
{
SqlConnection con = new SqlConnection();
string check;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button_Submit(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView2.Rows)
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["TestDeductionsConnectionString2"].ToString();
con.Open();
bool private1 = (row.FindControl("CheckBox1") as CheckBox).Checked;
if (private1 == true)
{
check = "1";
}
else
{
check = "0";
}
SqlCommand cmd = new SqlCommand("insert into DetailCosts(private) values(#private)", con);
cmd.Parameters.AddWithValue("#private", check);
cmd.ExecuteNonQuery();
}}
name of GridView is: GridView2;
name of Checkbox in the Table: private;
id of CheckBox in Gridview is:
<asp:TemplateField HeaderText="Private" SortExpression="private">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Eval("private") %>' />
</ItemTemplate>
<HeaderStyle HorizontalAlign="Center" />
</asp:TemplateField>
you can manually define a method to handle a postback generated by a control inside a gridview column. To do that you just need to add the tags AutoPostBack=True and OnCheckedChanged=YourMethodName to the control.
On the code-behind, define this method as public void, and define the parameters that usually would be there (sender as object and e as EventArgs), like:
public void YourMethodName(object sender, EventArgs e)
On the method, you may need to get the GridViewRow which contains the control that has generated the event. To do that, just parse the sender parameter (which will be the checkbox) and get 2 parent levels (GridViewCell and GridViewRow), it would be something like:
GridViewRow row = ((CheckBox)sender).parent.parent;
Since you have the row, you may get any control inside it with the FindControl method. If you need an id to identify the entitiy being updated, you may store it in a hidden field inside the row.
Hope it helps!
I have a problem that's been driving me nuts. Any help would be much appreciated. I have a grid view that displays what research items are assigned to what people. It should be possible to change the assignments using a dropdown. Here's the markup:
<asp:GridView ID="assignmentsGridView" runat="server" AutoGenerateColumns="false" CellPadding="2" Font-Size="Smaller"
OnRowDataBound="assignmentsGridView_RowDataBound" OnRowCommand="assignmentsGridView_RowCommand">
<Columns>
<asp:BoundField HeaderText="Ticker" DataField="Item" />
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:TemplateField HeaderText="Assignment" ItemStyle-HorizontalAlign="Center" ControlStyle-Font-Size="Small">
<ItemTemplate>
<asp:DropDownList ID="assignmentDropDown" runat="server" Visible="true"
OnSelectedIndexChanged="assignmentDropDown_SelectedIndexChanged" AutoPostBack="true" >
<asp:ListItem Text="Joe" Value="Joe"></asp:ListItem>
<asp:ListItem Text="Aron" Value="Aron"></asp:ListItem>
<asp:ListItem Text="Frank" Value="Frank"></asp:ListItem>
<asp:ListItem Text="Ross" Value="Ross"></asp:ListItem>
<asp:ListItem Text="Alex" Value="Alex"></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Analyst Complete" DataField="AnalystComplete" ItemStyle-HorizontalAlign="Center" ControlStyle-Font-Size="Smaller"/>
<asp:TemplateField HeaderText="Mark Complete" ControlStyle-Font-Size="Smaller">
<ItemTemplate>
<asp:Button ID="completeButton" runat="server" Text="Incomplete" CommandArgument='<%# Eval("Item") %>'
CommandName="Complete" Font-Size="Smaller" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I want to update the database when the user changes the SelectedIndex of the dropdown. I'm handling that here:
protected void assignmentDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
if (Session["IsCompany"] == null)
{
Session["IsCompany"] = assignmentsDropDown.SelectedValue == "Company";
}
bool? isCompany = Session["IsCompany"] as bool?;
int isCo = (isCompany == true) ? 1 : 0;
DropDownList ddl = sender as DropDownList;
GridViewRow gvr = ddl.NamingContainer as GridViewRow;
//ri is always 0!
int ri = gvr.RowIndex;
gvr = (GridViewRow)(((Control)sender).NamingContainer);
//ri is always 0!
ri = gvr.RowIndex;
gvr = ((GridViewRow)ddl.Parent.Parent);
//ri is always 0!
ri = gvr.RowIndex;
string selAnalyst = ddl.SelectedValue;
//selAnalsyt always = initial value!
selAnalyst = ddl.SelectedItem.Value;
//selAnalsyt always = initial value!
string ticker = gvr.Cells[0].Text;
//ticker always is first data row
}
As you can see in the comments, no matter what row I click, the GridViewRow associated with the sender argument is always the first row. Also, the selected value of the dropdown is always its initial value, not the value selected by the user that fired off the SelectedIndexChanged event.
I've searched for a solution to this problem online and found that it is often caused by (1) the databind event getting fired on postback and (2) duplicate rows in the source data. I have checked for duplicate data and solved that problem and put primary keys on the appropriate table. I'm also making sure not to rebind the data on postback. Here's the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.User.Identity.IsAuthenticated)
{
FormsAuthentication.RedirectToLoginPage();
}
else
{
string userName = Page.User.Identity.Name;
if (Session["UserMod"] == null)
{
this.userMod = new userModel(userName);
}
else
{
this.userMod = Session["UserMod"] as userModel;
}
if (!IsPostBack)
{
getPeopleList(userName);
getTickerList(userName);
if (this.userMod.IsResearchAdmin)
{
getAdminList();
}
else
{
assignmentsDropDown.Visible = false;
assignmentsGridView.Visible = false;
assignmentsButton.Visible = false;
assignmentsLabel.Visible = false;
addTextBox.Visible = false;
Image1.Visible = true;
analystDropdown.Visible = false;
}
}
}
}
I've got a RowDataBound method as well which sets the selected value of the dropdown for each row. When debugging, I have verified that the method is only running on the initial page load, not after the postback from SelectedIndexChanged. I was using an Update Panel as well, but removed that while trying to debug this.
I'm all outta ideas now, so I'm open to any suggestions. Thanks in advance
It looks like I've discovered an odd idiosyncrasy of asp.net. I had the following code in the RowDataBound method:
if (IsCompany)
{
e.Row.Cells.Remove(e.Row.Cells[1]);
}
I removed this code and the dropdown SelectedIndexChanged method now works correctly. All 3 methods of getting the parent GridViewRow of the dropdownlist are working after changing the RowDataBound method so that it does not remove any cells in the gridview.
I now believe that adding or removing cells during databinding causes unexpected problems with the SelectedIndexChanged event for dropdowns within GridViews. Here is the full code of the RowDataBoundMethod:
protected void assignmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (Session["IsCompany"] == null)
{
Session["IsCompany"] = entityDropDown.SelectedValue == "Company";
}
bool? isCompany = Session["IsCompany"] as bool?;
bool IsCompany = (bool)isCompany;
TableCell cell;
if (e.Row.RowType == DataControlRowType.DataRow)
{
cell = e.Row.Cells[0];
HyperLink link = new HyperLink();
if (IsCompany)
{
link.NavigateUrl = "~/CompanyPage.aspx?Ticker=" + cell.Text;
}
else
{
link.NavigateUrl = "~/PeoplePage.aspx?PersonId=" + cell.Text;
}
link.Text = cell.Text;
cell.Controls.Clear();
cell.Controls.Add(link);
/* with this code included, I experience problems with the SelectedIndexChanged event of the dropdown
if (IsCompany)
{
e.Row.Cells.Remove(e.Row.Cells[1]);
}
*/
cell = e.Row.Cells[2];
var dd = e.Row.FindControl("assignmentDropDown") as DropDownList;
string assignment = ((DataRowView)e.Row.DataItem)["Assignment"].ToString();
foreach (ListItem li in dd.Items)
{
if (li.Value == assignment)
{
li.Selected = true;
break;
}
}
cell = e.Row.Cells[4];
if (cell.Text == "False")
{
//"completeButton"
var cb = e.Row.FindControl("completeButton") as Button;
cb.Enabled = false;
cb.Visible = false;
}
else
{
((Button)cell.FindControl("completeButton")).CommandArgument = e.Row.RowIndex.ToString();
}
}
}
If someone could confirm that removing cells inside rowdatabound causes problems with the selected index change event in asp.net I'd appreciate it.
I have a GridCheckboxColumn in my grid and a need to create a GridTemplateColumn according to the checkbox is checked or not.
For instance,
line 1,
if the checkbox is checked the GridTempleColumn label displays "YES" ,
if the checkbox is not checked the GridTempleColumn label displays "NO",
if the checkbox is NULL : it displays "N/A".
To sum up, i have this in my aspx page:
<telerik:GridCheckBoxColumn DataField="facturable" DataType="System.Boolean" HeaderText="facturable"
SortExpression="facturable" UniqueName="facturable">
</telerik:GridCheckBoxColumn>
<telerik:GridTemplateColumn HeaderText="Type de tickets"
UniqueName="typedestickets">
<ItemTemplate><asp:Label id="test" runat="server"></asp:Label></ItemTemplate>
</telerik:GridTemplateColumn>
My try in code behind : ( not working )
protected void RadGrid1_DataBound(object sender, EventArgs e)
{
foreach (Telerik.Web.UI.GridDataItem dataItem in RadGrid1.MasterTableView.Items)
{
CheckBox chkDelete = (CheckBox)dataItem.FindControl("facturable");
Label label = (Label)dataItem.FindControl("test");
if (chkDelete.Checked == true) { label.Text = "MA"; }
}
}
Thank you in advance for your help
Check "e.item" is GridDataItem before accessing your controls. I perform a similar check in an application I'm working on, except I'm using "OnItemDatabound".
protected void grdSummary_OnItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
// Access your controls here
}
}
CheckBox checkboxfacturable = (CheckBox)dataItem["facturable"].Controls[0];
Label label = (Label)dataItem["typedestickets"].Controls[0];
Most controls, including grids, can bind a variety of objects, not just your data items. You should always check that e.Item is of the correct type first thing in your OnItemDataBound handler before using it.
I have a GridView with a DataSource (SQL Database). I want to hide a column, but still be able to access the value when I select the record. Can someone show me how to do this?
This is the column I want to hide and still want to access its value:
<asp:BoundField DataField="Outlook_ID" HeaderText="OutlookID" />
I tried everything to hide the column (property Visible="false"), but I can't access its value.
<head runat="server">
<title>Accessing GridView Hidden Column value </title>
<style type="text/css">
.hiddencol
{
display: none;
}
</style>
<asp:BoundField HeaderText="Email ID" DataField="EmailId" ItemStyle-CssClass="hiddencol" HeaderStyle-CssClass="hiddencol" >
</asp:BoundField>
ArrayList EmailList = new ArrayList();
foreach (GridViewRow itemrow in gvEmployeeDetails.Rows)
{
EmailList.Add(itemrow.Cells[YourIndex].Text);
}
If I am not mistaken, GridView does not hold the values of BoundColumns that have the attribute visible="false". Two things you may do here, one (as explained in the answer from V4Vendetta) to use Datakeys. Or you can change your BoundColumn to a TemplateField. And in the ItemTemplate, add a control like Label, make its visibility false and give your value to that Label.
Define a style in css:
.hiddencol { display: none; }
Then add the ItemStyle-CssClass="hiddencol" and the HeaderStyle-CssClass="hiddencol" attribute to the grid field:
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-CssClass="hiddencol" HeaderStyle-CssClass="hiddencol" ClientIDMode="Static" />
You can use DataKeys for retrieving the value of such fields, because (as you said) when you set a normal BoundField as visible false you cannot get their value.
In the .aspx file set the GridView property
DataKeyNames = "Outlook_ID"
Now, in an event handler you can access the value of this key like so:
grid.DataKeys[rowIndex]["Outlook_ID"]
This will give you the id at the specified rowindex of the grid.
You can do it programmatically:
grid0.Columns[0].Visible = true;
grid0.DataSource = dt;
grid0.DataBind();
grid0.Columns[0].Visible = false;
In this way you set the column to visible before databinding, so the column is generated.
The you set the column to not visible, so it is not displayed.
If you do have a TemplateField inside the columns of your GridView and you have, say, a control named blah bound to it. Then place the outlook_id as a HiddenField there like this:
<asp:TemplateField HeaderText="OutlookID">
<ItemTemplate>
<asp:Label ID="blah" runat="server">Existing Control</asp:Label>
<asp:HiddenField ID="HiddenOutlookID" runat="server" Value='<%#Eval("Outlook_ID") %>'/>
</ItemTemplate>
</asp:TemplateField>
Now, grab the row in the event you want the outlook_id and then access the control.
For RowDataBound access it like:
string outlookid = ((HiddenField)e.Row.FindControl("HiddenOutlookID")).Value;
Do get back, if you have trouble accessing the clicked row. And don't forget to mention the event at which you would like to access that.
You can make the column hidden on the server side and for some reason this is different to doing it the aspx code. It can still be referenced as if it was visible. Just add this code to your OnDataBound event.
protected void gvSearchResults_DataBound(object sender, EventArgs e)
{
GridView gridView = (GridView)sender;
if (gridView.HeaderRow != null && gridView.HeaderRow.Cells.Count > 0)
{
gridView.HeaderRow.Cells[UserIdColumnIndex].Visible = false;
}
foreach (GridViewRow row in gvSearchResults.Rows)
{
row.Cells[UserIdColumnIndex].Visible = false;
}
}
Leave visible columns before filling the GridView. Fill the GridView and then hide the columns.
Here is how to get the value of a hidden column in a GridView that is set to Visible=False: add the data field in this case SpecialInstructions to the DataKeyNames property of the bound GridView , and access it this way.
txtSpcInst.Text = GridView2.DataKeys(GridView2.SelectedIndex).Values("SpecialInstructions")
That's it, it works every time very simple.
I have a new solution hide the column on client side using css or javascript or jquery.
.col0
{
display: none !important;
}
And in the aspx file where you add the column you should specify the CSS properties:
<asp:BoundField HeaderText="Address Key" DataField="Address_Id" ItemStyle-CssClass="col0" HeaderStyle-CssClass="col0" > </asp:BoundField>
I used a method similar to user496892:
SPBoundField hiddenField = new SPBoundField();
hiddenField.HeaderText = "Header";
hiddenField.DataField = "DataFieldName";
grid.Columns.Add(hiddenField);
grid.DataSource = myDataSource;
grid.DataBind();
hiddenField.Visible = false;
I found this solution, an elegant(IMO) quick 2 parter.
1.
On your gridview, add a column as normal, no need to do anything differently:
<asp:BoundField DataField="AccountHolderName" HeaderText="Account Holder"
ReadOnly="true"/>
You can keep the header text if this is useful to you for later processing.
2.
In the rowdatabound method for the grid hide the header, footer and row for that column index:
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[10].Visible = false;
}
if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[10].Visible = false;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[10].Visible = false;
}
You can do it code behind.
Set visible= false for columns after data binding .
After that you can again do visibility "true" in row_selection function from grid view .It will work!!
I searched a lot but no luck. The most of them was working with some errors. Finally I used this code and it worked for me.
probably you should change 1 to some other value. for me I would hide second col.
protected void FoundedDrGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType!=DataControlRowType.Pager)e.Row.Cells[1].Visible = false;
}
I just set the width to 0. and it works.
columns.AddFor(m => m.Id).Name("hide-id").Width(0);
When I want access some value from GridView before GridView was appears.
I have a BoundField and bind DataField nomally.
In RowDataBound event, I do some process in that event.
Before GridView was appears I write this:
protected void GridviewLecturer_PreRender(object sender, EventArgs e)
{
GridviewLecturer.Columns[0].Visible = false;
}