I have a problem with my code. I need enable or disable a HyperLink in the RowDataBound event in an ASP.NET GridView based on a value extracted from the database.
If the value of field File of my database is not null, the HyperLink is visible otherwise not. In GridView, I don't have planned to show the value of field File.
I've tried using these solution without success, because I have this error.
Compiler Error Message: CS1502: The best overloaded method match for 'string.IsNullOrEmpty(string)' has some invalid arguments
Here is my code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink Srl = (HyperLink)e.Row.FindControl("Srl");
foreach (string color in colorList)
{
if (!string.IsNullOrEmpty(DataBinder.Eval(e.Row.DataItem, "File")))
{
Srl.Visible = true;
}
}
}
}
DataBinder.Eval returns an object. You need to convert that to a String.
Try this:
if (!string.IsNullOrEmpty(Convert.ToString(DataBinder.Eval(e.Row.DataItem, "File"))))
{
Srl.Visible = true;
}
<asp:GridView ID="gvList" runat="server" Width="100%" AutoGenerateColumns="False" AllowPaging="false">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="cbSelect" runat="server" />
<asp:HiddenField ID="hfSLNO_BARCODE" runat="server"
Value='<%#Bind("SLNO_BARCODE") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Use asp:HiddenField for File value and use this in row data bound event.
void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink Srl = (HyperLink)e.Row.FindControl("Srl");
foreach (string color in colorList)
{
string str = (string)DataBinder.Eval(e.Row.DataItem, "File");
//then you can check
if (!String.IsNullorEmpty(str ))
{
Srl.Visible = true;
}
}
}
}
Related
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:TextBox ID="TypeID" runat="server" Text='<%# Eval("Type") %>' />
</ItemTemplate>
</asp:TemplateField>
I want to remove this attribute Text='<%# Eval("Type") %>' programmatically on page load.
You can do it in the RowDatabound as shown below :
protected void GridViewName_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Hide the Textbox
TextBox txtboxtobehidden=
(TextBox)e.Row.FindControl("txtboxtobehidden");
txtboxtobehidden.Visible = false;
}
}
catch (Exception ex)
{
// your error Code
}
}
To avoid null exception on binding you can choose one option below:
You can change Text attribute in HTML Markup like:
Text='<%# Eval("Type").Tostring() == string.Empty ? "NA" : Eval("Type") %>'
Or, you can do it in Code-Behind like in RowDataBound event:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// find your textbox control in gridview
TextBox tb = (TextBox)e.Row.FindControl("txtboxtobehidden");
if(tb.Text == "")
{
// To remove Text attribute
tb.Attributes.Remove("Text");
// tb.Text = "NA";
}
}
}
I have used grid view in my ASP.NET application.
<asp:GridView ID="grdView" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkbox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Jurisdiction">
<ItemTemplate>
<asp:Label ID="lblJurisdiction" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="License Number">
<ItemTemplate>
<asp:TextBox ID="txtLicenseNumber" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
in cs file
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in grdView.Rows)
{
for (int i = 0; i < grdView.Columns.Count; i++)
{
String cellText = row.Cells[i].Text;
}
}
}
Note that the above grid will be populated by data. Now I need to get data from already populated gridview. The above code is not working. Also I need to retrieve from labels, textboxes, checkboxes values inside grid. Please help !!!
You can use FindControl method to retrieve the control's data:-
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in grdView.Rows)
{
CheckBox chkbox = row.FindControl("chkbox") as CheckBox;
Label lblJurisdiction = row.FindControl("lblJurisdiction") as Label;
..and so on
//Finally retrieve the data like your normal control
string labelText = lblJurisdiction.Text;
}
}
Use GridViewRow.FindControl method.
foreach (GridViewRow row in grdView.Rows)
{
// return you the check-box control from current row
var chkbox = row.FindControl("chkbox");
}
Check whether the row type is DataControlRowType.DataRow.
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in grdView.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < grdView.Columns.Count; i++)
{
String cellText = row.Cells[i].Text;
}
}
}
}
To get the TextBox, CheckBox value from the grid use this,
string TextBoxvalue = ((TextBox)GridViewID.Rows[i].FindControl("TextBoxName")).Text;
string CheckBoxvalue = ((CheckBox)GridViewID.Rows[i].FindControl("CheckBoxName")).Text;
In your code .cs file, you are missing to check only for datarow. As it will check all 3 places:-
1. Header
2. Body
3. Footer
Might any one place, any exception can occur.
Please add one more if condtion just after the for loop, as below.
if (row.RowType == DataControlRowType.DataRow)
{
Hope this post will help's you :).
Use
cells[i].EditedFormatedValue
Code Behind
public void lbDelete_Click(object sender, EventArgs e)
{
LinkButton lb = sender as LinkButton;
GridViewRow gvrow = lb.NamingContainer as GridViewRow;
gvsize.DeleteRow(gvrow.RowIndex);
}
GridView:
<asp:GridView ID="gvsize" runat="server" ShowFooter="True" CellPadding="1" CellSpacing="2" AutoGenerateColumns="false" GridLines="Horizontal">
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="lnkdelete" runat="server" ForeColor="Blue" OnClick="lbDelete_Click">Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView >
There are 2 rows in my gridview which I need to delete the row using the function above.
It throws an error "gvsize" RowDeletingEvent was not handled properly.
Is that necessary to use OnRowDeleted/OnRowDeleting in gridview which I feel not necessary??
As stated in How to delete row from gridview?
You are deleting the row from the gridview but you are then going and
calling databind again which is just refreshing the gridview to the
same state that the original datasource is in.
Either remove it from the datasource and then databind, or databind
and remove it from the gridview without redatabinding.
You can use row databound event to accomplish this task.
<asp:LinkButton ID="lnkBtnDel" runat="server" CommandName="DeleteRow" OnClientClick="return confirm('Are you sure you want to Delete this Record?');"">Delete</asp:LinkButton>
and in the rowdatabound event you can have
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DeleteRow")
{
//incase you need the row index
int rowIndex = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;
//followed by your code
}
}
Try this to delete row
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
dt.Rows.RemoveAt(e.RowIndex);
GridView1.DataSource = dt;
GridView1.DataBind();
}
You can also delete row from another method using Template Column
ASPX
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="imgDelete" runat="server" CommandName="deletenotice" ImageUrl="~/images/delete1.gif" alt="Delete"
OnClientClick="return confirm('Are you sure want to delete the current record ?')">
</asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
C# Code
protected void gvNoticeBoardDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToLower().Equals("deletenotice"))
{
GridViewRow row = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
NoticeBoard notice = new NoticeBoard();
HiddenField lblCust = (HiddenField)row.FindControl("hdngvMessageId");//Fetch the CourierId from the selected record
auditTrail.Action = DBAction.Delete;
Service simplyHRClient = new Service();
MessageClass messageClass = simplyHRClient.SaveNoticeBoard(notice, auditTrail);
if (messageClass.IsSuccess)
{
this.Page.AddValidationSummaryItem(messageClass.MessageText, "save");
showSummary.Style["display"] = string.Empty;
showSummary.Attributes["class"] = "success-message";
if (messageClass.RecordId != -1)
lblCust.Value = messageClass.RecordId.ToString();
}
else
{
this.Page.AddValidationSummaryItem(messageClass.MessageText, "save");
showSummary.Style["display"] = string.Empty;
showSummary.Attributes["class"] = "fail-message";
}
//Bind Again grid
GetAllNoticeBoard();
}
}
Hope it helps you
I have gridview in an asp.net application. I want to insert a column with image buttons where by click on it will enable or disable users or change the status field in db and also change the image button image accordingly user status.
Meaning: I want to display different images for disabled and enabled users.
How can I do this in C# and bind the data to the image button?
Anyone please help. Thanks in advance.
Make use of the ItemDataBound event. This is where you can check each row of your grid and apply changes to it. Then you can hide / unhide or change buttons:
VB.net below but you can easily convert to C#:
Dim ib As ImageButton = CType(e.Item.FindControl("ibFav"), ImageButton)
ib.Visible = False
Dim ib2 As ImageButton = CType(e.Item.FindControl("ibRemFav"), ImageButton)
ib2.Visible = True
Sample User Model:
public class UserModel {
public string Name { get; set; }
public bool IsEnabled { get; set; }
}
Here is the GridView Code:
<asp:GridView ID="GridView" runat="server" AutoGenerateColumns="false"
onrowcommand="GridView_RowCommand" onrowdatabound="GridView_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemStyle HorizontalAlign="Center" />
<ItemTemplate>
<asp:ImageButton ID="EnabledImgBtn" runat="server"
CommandArgument='<%# Eval("Name") %>'
CommandName="ResetUserState" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
//Other columns....
</Columns>
</asp:GridView>
Set the 'CommandArgument' according to your needs. e.g the ID of the User.
Sample Code-behind for the gridview:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack){
LoadGridView();
}
}
private void LoadGridView()
{
this.GridView.DataSource = GetUsersFromDatabase();
this.GridView.DataBind();
}
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var user = e.Row.DataItem as UserModel;
var enabledImgBtn = e.Row.FindControl("EnabledImgBtn") as ImageButton;
if (enabledImgBtn != null)
enabledImgBtn.ImageUrl = user.IsEnabled ? "~/YourImagePath/enabled.png"
: "~/YourImagePath/disalbed.png";
}
}
protected void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "ResetUserState")
{
if (e.CommandArgument!= null)
{
var userName = e.CommandArgument.ToString();
//Change user enabled state and Update database
//Sample code:
var user = FindUserByName("userName");
user.IsEnabled = !user.IsEnabled;
//SaveInDatabase(user);
LoadGridView();
}
}
}
You may consider using 'CommandField' with Type equal to 'Image' instead of 'TemplateField', but there is an issue with this approach, read more.
Hope this helps.
<asp:GridView ID="GridView" runat="server" AutoGenerateColumns="false"
onrowcommand="GridView_RowCommand" onrowdatabound="GridView_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Change Status" ItemStyle-CssClass="GrdItemImg">
<ItemTemplate>
<asp:ImageButton ID="ibtnChangeActiveStatus" CommandArgument='<%#Eval("RecordID")%>'
CommandName='GRDSTATUS' runat="server" ImageUrl='<%# getStatusImage(Convert.ToInt32(DataBinder.Eval(Container.DataItem,"IsApproved"))) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Col2" HeaderText="Col2" />
//Other Respective columns....
...........
..........
</Columns>
</asp:GridView>
And In CS file add the following function.
public string getStatusImage(int intStatus)
{
string strStatus = string.Empty;
if (intStatus == 1)
{
strStatus = "~/images/active.png";
}
else
{
strStatus = "~/images/inactive.png";
}
return strStatus;
}
So on the base of "intStatus" respective active / InActive Image will be set.
I have a GridView on my aspx page which displays a collection of objects defined by the following class
public class Item
{
public string ItemName{get; set;}
public object ItemValue{get; set;}
}
Then in my aspx markup I have something like this
<asp:GridView ID="MyTable" runat="server">
<Columns>
<asp:BoundField DataField="ItemName" />
<asp:BoundField DataField="ItemValue" />
</Columns>
</asp:GridView>
What I want to know is:
Is there a way to use conditional formatting on the ItemValue field, so that if the object is holding a string it will return the string unchanged, or if it holds a DateTime it will displays as DateTime.ToShortDateString().
Not sure if you can use a BoundField, but if you change it to a TemplateField you could use a formatting function like in this link.
ie something like
<%# FormatDataValue(DataBinder.Eval(Container.DataItem,"ItemValue")) %>
Then in your codebehind, you can add a Protected Function
Protected Function FormatDataValue(val as object) As String
'custom enter code hereformatting goes here
End Function
Or you could do something in the OnRowCreated event of the gridview, like in this link
<asp:GridView ID="ctlGridView" runat="server" OnRowCreated="OnRowCreated" />
this function is conditional formatting based on whether or not the datavalue is null/is a double
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView drv = e.Row.DataItem as DataRowView;
Object ob = drv["ItemValue"];
if (!Convert.IsDBNull(ob) )
{
double dVal = 0f;
if (Double.TryParse(ob.ToString(), out dVal))
{
if (dVal > 3f)
{
TableCell cell = e.Row.Cells[1];
cell.CssClass = "heavyrow";
cell.BackColor = System.Drawing.Color.Orange;
}
}
}
}
}
With BoundField you should modify your Item class.
If you don't want to modify your CodeBehind ther is a sort of trick you can do using a TemplateField:
<asp:GridView ID="MyTable" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ItemName" HeaderText="Name" />
<asp:TemplateField HeaderText="Value">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# ((Eval("ItemValue") is DateTime) ? ((DateTime)Eval("ItemValue")).ToShortDateString() : Eval("ItemValue")) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
obviously you can do it for any type of object but maybe your "Text" field would become.. complicated..
by the way.. my CodeBehind for this example was just you class Item and this Page_Load():
protected void Page_Load(object sender, EventArgs e)
{
Item i1 = new Item();
i1.ItemName = "name1";
i1.ItemValue = "foo";
Item i2 = new Item();
i2.ItemName = "name2";
i2.ItemValue = DateTime.Now;
List<Item> list1 = new List<Item>();
list1.Add(i1);
list1.Add(i2);
MyTable.DataSource = list1;
MyTable.DataBind();
}
and the result was correct ;)
i decided with the Paul Rowland solution and more one thing "if (e.Item.DataItem is DataRowView)":
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
if (e.Item.DataItem is DataRowView)
{
DataRowView rowView = (DataRowView)e.Item.DataItem;
String state = rowView[PutYourColumnHere].ToString();
if (state.Equals("PutYourConditionHere"))
{
//your formating, in my case....
e.Item.CssClass = "someClass";
}
}
}
In .NET 2.0 is even easier:
Add this method to code behind: (this example formats a double value as million with 1 digit)
public string EvalAmount(string expression)
{
double? dbl = this.Eval(expression) as double?;
return dbl.HasValue ? string.Format("{0:0.0}", (dbl.Value / 1000000D)) : string.Empty;
}
In the aspx code, use this:
<asp:TemplateField ItemStyle-Width="100px">
<ItemTemplate>
<asp:Label runat="server" Text='<%# EvalAmount("MyAmount") %>'></asp:
</ItemTemplate>
</asp:TemplateField>