Blank Gridview Cell populates "&nbsp" into textbox - asp.net

I've noticed that when i populate textboxes from a selected row in a gridview that if the field is blank it displays "&nbsp" in the textbox.
Here is the solution I came up with. I check each cell before adding it to the textbox.
I get the feeling that I'm either doing something wrong to have this problem in the first place or that there is a better way to handle this.
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//// Get the currently selected row using the SelectedRow property.
GridViewRow row = GridView1.SelectedRow;
// Load data from selected row into textboxes
if (row.Cells[1].Text.Trim() != " ")
{
txtEditCust_ID.Text = row.Cells[1].Text.Trim();
}
}

Still a minor hack, but probably better than dealing with . You can set NullDisplayText=" " on GridView column <asp:BoundField> and then use condition like for example:
if (String.IsNullOrWhiteSpace(e.Row.Cells[1].Text))
{
// do something with e.Row
}
In this case, there is no to begin with.

row.Cells[1].Text.Trim()
is not working for , replace it instead:
row.Cells[1].Text.Replace(" ", "")

This works too. Add this piece of code under your rowDataBound event
if (e.Row.Cells[1].Text.Length == 0 || e.Row.Cells[1].Text.Equals(" ") || e.Row.Cells[1].Text.Equals("") || e.Row.Cells[1].Text.Equals(string.Empty))
{
e.Row.Cells[1].Text = string.Empty;
}

use
txtEditCust_ID.Text = Server.HtmlDecode(row.Cells[1].Text.Trim());

Remove the if statement, just use:
txtEditCust_ID.Text = row.Cells[1].Text.Trim();
You are trimming it so it should remove the anyway.

if (e.Row.RowType != DataControlRowType.Header && e.Row.RowType != DataControlRowType.Footer && e.Row.RowType != DataControlRowType.Pager)
This removes the header, footer, and pager (if you are using) rows which took care of the for me.

If you want to check the gridview cell value whether empty or null, use this:
string decodeCellValue = Context.Server.HtmlDecode(e.Row.Cells[i].Text).Trim();
if(string.IsNullOrEmpty(decodeCellValue))
{
// Cell value empty or NULL
}
else
{
// Have some value
}

Related

How do i use Checkboxes in gridview to show data

I Have Two Gridview in first one there is some data with checkbox. I Want when i check two or more checkboxes then show the both record who's checked to another gridview There is my Coding. Problem is it's show only one record at a time..
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
foreach(GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow )
{
CheckBox chkSelect = (CheckBox)row.Cells[0].FindControl("CheckBox1");
if (chkSelect != null)
{
if (chkSelect.Checked)
{
string FoodItem = ((Label)row.FindControl("Label1")).Text.ToString();
string s = "select * from Item where Item_Name='" + FoodItem + "' ";
db.grid(s, GridView2);
}
}
}
}
By looking your code,
first think dont bind gridview immediately after checking checked property of each check box, it will override gridview2. first collect all check box values by concatinating say FoodItem = "(value1,value2,value3)".
call data base one time by modifying query like
string s = "select * from Item where Item_Name in " + FoodItem +";
db.grid(s, GridView2);
I think you have multiple selection so keep seperate button and write all codes to copy from one grid to another grid inside button click event.

How can I get selected row cell value of grid view on page?

I am using a Grid View on my page.
I want to show the data of the selected row cell through response.write(), on the click event of the page button.
Note::
please set the CommandName of your
button to "selectCol"
Please set the CommandName for the
second button , you will use to
delete
to"deleteCol"
Set the command argument property for your button :
.aspx
CommandArgument='<%#((GridViewRow)Container).RowIndex%>'
CommandArgument='<%#((GridViewRow)Container).RowIndex%>'
for the two buttons.
.cs
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
int index = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "selectCol")
{
Response.Write(gv.Rows[index].Cells[0].Text); //consider you use bound field and the column you want to show its value is the first column.
}
else if(e.CommandName == "deleteCol")
{
int id = int.Parse(gv.DataKeys[index].Value.ToString());//the primary key for your table.
Delete(id);//method which use (Delete From .... Where id = ....).
}
gv.DataBind();
}
catch (Exception ee)
{
string message = ee.Message;
}
}
Greeting Hims.
Easyest way to read value from gridview field is to write:
your_grid_name.SelectedRow.Cell(*number_of_index*).text
In my case that is:
Dim employer_name As String
employer_name=poslodavac_grid.SelectedRow.Cells(1).Text
Just remember that first cell index is zero and that doesn't count "asp:CommandField ShowSelectButton" tag as first one ...
Use GridView.SelectedRow property.
String cellText = this.gridView.SelectedRow.Cells[cellIndex].Text;
Refer to the following to learn about selecting a row in a GridView control.
Select Command in a GridView Control in ASP.Net
If you are using a LINK BUTTON in your grid view, you can use the following code in the ROWCOMMAND method. This code with retrieve all the values in the particular selected row.
// to get the value of the link use the command argument
FaultId = Convert.ToInt32(e.CommandArgument);
// to get the other column values
UserId = Convert.ToInt32(((GridViewRow(((LinkButton)e.CommandSource).NamingContainer)).Cells[1].Text);
Department = ((GridViewRow(((LinkButton)e.CommandSource).NamingContainer)).Cells[2].Text;
ProblemType = ((GridViewRow)(((LinkButton)e.CommandSource).NamingContainer)).Cells[3].Text;
You can get it in the RowCommand event of the gridview:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
Response.Write(row.Cells[0].Text);
Response.Write(row.Cells[1].Text);
................
}
}

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);

C#,ASP.NET: Formatting a GRIDVIEW row Based on Content

Greetings Gurus. I have a gridview who's rows I need to higlight if the 'Status' field is null. The code below throws an exception. I'm getting a "Non-invocable member 'System.Web.UI.WebControls.GridViewRow.DataItem' cannot be used like a method". I think I'm really close but I don't know where to turn next.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
e.Row.DataItem("Status") == null)
{
// e.Row.BackColor = Drawing.Color.Red;
}
}
basic
CType(e.Row.DataItem, DataRowView)("Status") = null
c#
((DataRowView)e.Row.DataItem)["Status"] == null
or do it in more than one line -- see example here:
msdn example
I haven't looked at this in a long while but do you access DataItem like an array??
e.Row.DataItem("Status") would be e.Row.DataItem["Status"]
Look here
// Retrieve the underlying data item. In this example
// the underlying data item is a DataRowView object.
DataRowView rowView = (DataRowView)e.Row.DataItem;
// Retrieve the state value for the current row.
String state = rowView["state"].ToString();
Try casting:
if (((MyType)e.Row.DataItem).Status == null) { ... }
Have a look at the sample code at MSDN.
The key points are:
Cast your DataRow to a DataRowView,
like this:
DataRowView rowView = (DataRowView)e.Row.DataItem;
You can then retrieve values like
this:
// Retrieve the status value for the current row.
Status status = (Status)rowView["status"];
...or cast to whatever type Status happens to be.
Got it. It may not be the best solution but it works.
if (e.Row.RowType == DataControlRowType.DataRow )
{
DataRowView test = (System.Data.DataRowView)e.Row.DataItem;
string Active = test.Row[4].ToString();
if(Active == "")
{
e.Row.BackColor = System.Drawing.Color.Sienna;
e.Row.ForeColor = System.Drawing.Color.Yellow;
}
}

ASP.Net Grid View rolling total in Gridview

I have seen several tutorials on how to achieve this.
However in my opinion they require a lot of prior knowledge on how to programatically refer to each item.
Does anyone have a link to or can create a relatively basic example of how to achive a running total in the footer for an ASP:Gridview?
This is what I use:
protected void InvoiceGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
var invoice = (Invoice) e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.Header)
{
totalAmt = 0;
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
totalAmt += invoice.Amount;
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
var amountTotalLabel = (TextBox) e.Row.FindControl("AmountTotalTextBox");
amountTotalLabel.Text = totalAmt.ToString("0.00");
}
}
TotalAmt is protected instance variable on the page. Not sure if it's what you were looking for based on your comment about "programmatic knowledge." But it works and is fairly straight-forward. The gridview is bound to a List<Invoice> in this case.
Add the footer Template and on the RowDataBound, have a global variable to store the summation sum,
At the e.Row.RowType = DataControlRowType.DataRow type do the summation , and # the e.Row.RowType = DataControlRowType.Footer store the vale in the appropriate cell
for further info look # MSDN LINK
This is how I do it. Very easy. You just sum the row that has your numbers in it and place it in the footer.
((Label)GridView.FooterRow.Cells[1].FindControl("your_label")).Text = ds.Tables[0].Compute("sum(Column_name)", "").ToString();
I think the method I use is pretty basic and doesn't require programatically referring to columns in the Gridview, if that's what you mean. That's one of the nice parts is that once you get the back-end functions written, you can add totals to any Gridview by only editing the .aspx file.
In your GridView, make the column like this:
<asp:TemplateField HeaderText="Hours">
<ItemTemplate><%#DisplayAndAddToTotal(Eval("Hours").ToString(), "Hours")%></ItemTemplate>
<FooterTemplate><%#GetTotal("Hours")%></FooterTemplate>
</asp:TemplateField>
The second parameter to DisplayAndAddToTotal can be any string you want as long as you use the same string in GetTotal. I usually just use the field name again though. Here are the two functions used, DisplayAndAddToTotal and GetTotal. They use a Hashtable to store the totals so that it works with any number of columns you want to add up. And they also work with counting the number of "True"s for a Boolean field.
Protected total As Hashtable = New Hashtable()
Protected Function DisplayAndAddToTotal(itemStr As String, type As String) As Double
Dim item As Double
If itemStr = "True" Then
item = 1
ElseIf Not Double.TryParse(itemStr, item) Then
item = 0
End If
If total.ContainsKey(type) Then
total(type) = Double.Parse(total(type).ToString()) + item
Else
total(type) = item
End If
Return item
End Function
Protected Function GetTotal(type As String) As Double
Try
Dim result As Double = Double.Parse(total(type).ToString())
Return result
Catch
Return 0
End Try
End Function

Resources