how to bind substring into gridview and - asp.net

I am using a gridview to show my db table data. but there is a column called "Description " with 1000 characters. I don't want bond whole string into gridview. How I bind only first 100 characters into gridview column???
when I click select button I want make to popup window with selected column details. At this moment I want to show all characters of Description column.
I have already created popup window and other things. but still I could not get first 100 letters of "description column" and bind it into gridview. How can I do this ? And how I get whole string into popup window?
ALL ANSWERS ARE WELCOME.. PLEASE HELP ME.
THANK YOU

If you have an entity that you bind to your gridview, you can do this:
First, add a new property:
[NotMapped]
public string CutDescription
{
get
{
if (Description.Length <= 1000)
{
return Description;
}
return Description.Substring(0, 1000) + "...";
}
}
Then you can bind this to your gridview:
<asp:BoundField DataField="CutDescription" HeaderText="Description" />
This is just one way to do it. Hope it helps.
EDIT:
Another way using RowDatabound event:
protected void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
var row = e.Row;
if (row.RowType == DataControlRowType.DataRow)
{
// Just change the index of the cell
var description = row.Cells[1].Text;
if (description.Length > 100)
{
row.Cells[1].Text = description.Substring(0, 100) + "...";
}
}
}

I fond the solution myself
100% working and fully tested
protected void grdName_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[8].Text.Length > 100)
{
e.Row.Cells[8].Text = e.Row.Cells[8].Text.Substring(0, 12);
}
}
}

Related

Loop through a gridview to replace the cell value

I want to loop through a gridview cell values and replace any value which has an asterisk like 3*,4*, ** etc to change like 3(underline), 4 underline and 8 (underline)..so basically i want to remove the asterisk and underline the inetger..Please guide me on this...thank you
You can loop trough every row and cell trough this:
foreach(DataGridViewRow gridRow in myGridview.Rows)
{
for(int i = 0; i < myGridview.Columns.Count; i++)
{
if(gridRow.Cells[i].Text.Contains('*'))
{
//Do your thing
gridRow.Cells[i].Text=gridRow.Cells[i].Text.Replace(#"*", "");
gridRow.Cells[i].Style.Font = new Font("Ariel", 8, FontStyle.Underline);
}
}
}
You can achieved this by using RowDataBound Event.. No need to loop
GridView.RowDataBound Event
The following example demonstrates how to use the RowDataBound event to modify the value of a field in the data source before it is displayed in a GridView control.
void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Display the company name in italics.
e.Row.Cells[1].Text = "<i>" + e.Row.Cells[1].Text + "</i>";
}
}

accessing selected checkboxes in gridview

i have a gridview in which i am using checkbox in each row. i am trying to access checkbox of each row and trying to find out which checkboxes have been checked.buut when i try to run the below code.the condition always stands to be false and the inner if condition is never reached by the code.kindly help me.thanks in advance.
protected void btn_3id_Click(object sender, EventArgs e)
{
string str = "";
string srr = "";
for (int i = 0; i < GridView1.Rows.Count;i++ )
{
CheckBox chk = (CheckBox)GridView1.Rows[i].FindControl("CheckBox1");
if (chk.Checked==true)
{
if (str == "")
{
str = GridView1.Rows[i].Cells[0].Text.ToString();
}
else
{
srr = str + "," + GridView1.Rows[i].Cells[0].Text.ToString();
}
}
}
Session["Card_id"] = str;
Response.Redirect("ID.aspx");
}
The code looks fine.
The problem could be you are binding the gridview at page load.
Try grid binding in the following section of page load
if(!Page.IsPostBack)
{
//code to bind the gridview
}
I can only guess that you are binding your gridview on each page load without checking PostBack. That is causing the checkbox to loose its current state. So where you are assigning the DataSource to the Gridview , Check for PostBack like:
if(!Page.IsPostBack)
{
GridView1.DataSource = yourDataSource;
GridView1.DataBind();
}
also you can do some minor improvements in your code like your check:
if(chk.Checked == true)
can be replaced as:
if(chk.Checked) //Since it returns a bool value.
You can omit multiple string variables for concatenation. Its better if you use StringBuilder, (See why it is better) so your code would be:
protected void btn_3id_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < GridView1.Rows.Count;i++ )
{
CheckBox chk = (CheckBox)GridView1.Rows[i].FindControl("CheckBox1");
if (chk.Checked==true)
{
sb.Append() GridView1.Rows[i].Cells[0].Text.ToString();
}
}
Session["Card_id"] = sb.ToString();
Response.Redirect("ID.aspx");
}
if(!Page.IsPostBack)
{
//
}
Postback plays important role in cs file. If you are clearing values on page load , you will null values of checkbox.
You code is fine.
Just try to do this...

Unable to FindControl() in ListView ItemEditing

I have a ListView in an ASP.NET web application. When a user clicks the edit button, I want textfields to pop up that are dependent on certain values of the item. However, I can't seem to find any controls inside of my ListView1_ItemEditing() function.
I have read the Microsoft documentation and various help threads on the internet, but their suggestions do not appear to work for me. This is generally what I see:
ListViewItem item = ProductsListView.Items[e.NewEditIndex];
Label dateLabel = (Label)item.FindControl("DiscontinuedDateLabel");
For the sake of simplicity I just want to be able to select a label in ListView1_ItemEditing(). This is the code in ListView1_ItemEditing():
protected void ListView1_ItemEditing(Object sender, ListViewEditEventArgs e)
{
DataBind(); //not sure if this does anything
ListViewItem item = ListView1.Items[e.NewEditIndex];
Label debugLabel = (Label)item.FindControl("label_editing");
debugLabel.Text = "Works";
}
Here is the ASP
<EditItemTemplate>
<asp:Label ID="label_editing" runat="server" Text="hello world"></asp:Label>
</EditItemTemplate>
When debugging, item and debugLabel are both NULL.
UPDATE: I resolved this issue by moving my logic to ItemDataBound and then checking if my tr (containing textboxes) was in that particular data item. Code below:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Control tr_verizon = e.Item.FindControl("tr_verizonEdit");
Control tr_att = e.Item.FindControl("tr_attEdit");
if (tr_verizon != null)
{
//Control tb_meid = e.Item.FindControl("TextBox_Meid");
Label lbl_carrierId = (Label)e.Item.FindControl("lbl_carrierId");
if (lbl_carrierId == null)
{
Message.Text = "lbl_carrierId is null!";
}
else if (lbl_carrierId.Text.Equals(""))
{
Message.Text = "lbl_carrierId is empty!";
}
else
{
string recordId = lbl_carrierId.Text;
if (tr_verizon != null && tr_att != null)
{
if (lbl_carrierId.Text.Equals("1"))
{
tr_verizon.Visible = false;
tr_att.Visible = true;
}
else
{
tr_verizon.Visible = true;
tr_att.Visible = false;
}
}
}
}
}
}
The ItemEditing event is raised when an item's Edit button is clicked, but before the ListView item is put in edit mode. Therefore controls in EditItemTemplate are not available at this time.
More Info and example
You should do the DataBind() first, like this:
ListView1.EditIndex = e.NewEditIndex;
ListView1_BindData(); // a function that get the DataSource and then ListView1.DataBind()
// Now find the control as you did before
Have you tried casting the sender object instead of trying to access your ListViewItem by index?
protected void ListView1_ItemEditing(Object sender, ListViewEditEventArgs e)
{
var item = sender as ListViewItem;
var debugLabel = item.FindControl("label_editing") as Label;
debugLabel.Text = "Works";
}

How to get the cell value by column name not by index in GridView in asp.net

I am having a gridview in asp.net and now I want the cell value by the column name but not by the cell index.
How would be it possible by retrieving the cell value by the cell column name
GridView does not act as column names, as that's it's datasource property to know those things.
If you still need to know the index given a column name, then you can create a helper method to do this as the gridview Header normally contains this information.
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
break;
columnIndex++; // keep adding 1 while we don't have the correct name
}
return columnIndex;
}
remember that the code above will use a BoundField... then use it like:
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int index = GetColumnIndexByName(e.Row, "myDataField");
string columnValue = e.Row.Cells[index].Text;
}
}
I would strongly suggest that you use the TemplateField to have your own controls, then it's easier to grab those controls like:
<asp:GridView ID="gv" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and then use
string columnValue = ((Label)e.Row.FindControl("lblName")).Text;
Although its a long time but this relatively small piece of code seems easy to read and get:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
int index;
string cellContent;
foreach (TableCell tc in ((GridView)sender).HeaderRow.Cells)
{
if( tc.Text.Equals("yourColumnName") )
{
index = ((GridView)sender).HeaderRow.Cells.GetCellIndex(tc);
cellContent = ((GridView)sender).SelectedRow.Cells[index].Text;
break;
}
}
}
You can use the DataRowView to get the column index.
void OnRequestsGridRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var data = e.Row.DataItem as DataRowView;
// replace request name with a link
if (data.DataView.Table.Columns["Request Name"] != null)
{
// get the request name
string title = data["Request Name"].ToString();
// get the column index
int idx = data.Row.Table.Columns["Request Name"].Ordinal;
// ...
e.Row.Cells[idx].Controls.Clear();
e.Row.Cells[idx].Controls.Add(link);
}
}
}
For Lambda lovers
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var boundFields = e.Row.Cells.Cast<DataControlFieldCell>()
.Select(cell => cell.ContainingField).Cast<BoundField>().ToList();
int idx = boundFields.IndexOf(
boundFields.FirstOrDefault(f => f.DataField == "ColName"));
e.Row.Cells[idx].Text = modification;
}
}
Based on something found on Code Project
Once the data table is declared based on the grid's data source, lookup the column index by column name from the columns collection. At this point, use the index as needed to obtain information from or to format the cell.
protected void gridMyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = (DataTable)((GridView)sender).DataSource;
int colIndex = dt.Columns["MyColumnName"].Ordinal;
e.Row.Cells[colIndex].BackColor = Color.FromName("#ffeb9c");
}
}
Header Row cells sometimes will not work. This will just return the column Index. It will help in a lot of different ways. I know this is not the answer he is requesting. But this will help for a lot people.
public static int GetColumnIndexByHeaderText(GridView gridView, string columnName)
{
for (int i = 0; i < gridView.Columns.Count ; i++)
{
if (gridView.Columns[i].HeaderText.ToUpper() == columnName.ToUpper() )
{
return i;
}
}
return -1;
}
A little bug with indexcolumn in alexander's answer:
We need to take care of "not found" column:
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
int foundIndex=-1;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
{
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
{
foundIndex=columnIndex;
break;
}
}
columnIndex++; // keep adding 1 while we don't have the correct name
}
return foundIndex;
}
and
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int index = GetColumnIndexByName(e.Row, "myDataField");
if( index>0)
{
string columnValue = e.Row.Cells[index].Text;
}
}
}
We can get it done in one line of code. No need to loop through anything or call other methods.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string cellValue = e.Row.Cells[e.Row.Cells.GetCellIndex(e.Row.Cells.Cast<DataControlFieldCell>().FirstOrDefault(cell => cell.ContainingField.HeaderText == "columnName"))].Text;
}
}
//get the value of a gridview
public string getUpdatingGridviewValue(GridView gridviewEntry, string fieldEntry)
{//start getGridviewValue
//scan gridview for cell value
string result = Convert.ToString(functionsOther.getCurrentTime());
for(int i = 0; i < gridviewEntry.HeaderRow.Cells.Count; i++)
{//start i for
if(gridviewEntry.HeaderRow.Cells[i].Text == fieldEntry)
{//start check field match
result = gridviewEntry.Rows[rowUpdateIndex].Cells[i].Text;
break;
}//end check field match
}//end i for
//return
return result;
}//end getGridviewValue
It is possible to use the data field name, if not the title so easily, which solved the problem for me. For ASP.NET & VB:
e.g. For a string:
Dim Encoding = e.Row.DataItem("Encoding").ToString().Trim()
e.g. For an integer:
Dim MsgParts = Convert.ToInt32(e.Row.DataItem("CalculatedMessageParts").ToString())
protected void CheckedRecords(object sender, EventArgs e)
{
string email = string.Empty;
foreach (GridViewRow gridrows in GridView1.Rows)
{
CheckBox chkbox = (CheckBox)gridrows.FindControl("ChkRecords");
if (chkbox != null & chkbox.Checked)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in gridrows.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals("UserEmail"))
break;
columnIndex++;
}
email += gridrows.Cells[columnIndex].Text + ',';
}
}
Label1.Text = "email:" + email;
}
protected void gvResults_PreRender(object sender, EventArgs e)
{
var gridView = (GridView)sender;
gridView.GetColumnByName("YourDataBoundDataField").Visible = true;
}
Extension:
public static DataControlField GetColumnByName(this GridView gridView, string columnName)
{
int columnIndex = -1;
for (int i = 0; i < gridView.Columns.Count; i++)
{
if (gridView.Columns[i].HeaderText.Trim().Equals(columnName, StringComparison.OrdinalIgnoreCase))
{
columnIndex = i;
break;
}
}
if (columnIndex == -1)
{
throw new ArgumentOutOfRangeException("GridViewRow does not have the column with name: " + columnName);
}
return gridView.Columns[columnIndex];
}
The primary reason this would be difficult is because gridview cells do not have accessible cell names (ugh).
In order to work around this handicap you can make an extension method (mine is in VB.NET, but #Дмитрийh seems to have a similar solution in C#).
To work around this ensure the HeaderText of the gridview cells have the same value as the cellnames and grab the values via that HeaderText name.
Here is extension methods you would need for strings and integers in a VB.NET code snippet that I made
Public Shared Function GetStringByCellName(pGridViewRow As GridViewRow, pCellName As String) As String
For Each myCell As DataControlFieldCell In pGridViewRow.Cells
If myCell.ContainingField.ToString() = pCellName Then
Return myCell.Text
End If
Next
Return Nothing
End Function
And the difference for integers being a parse/cast
Public Shared Function GetIntegerByCellName(pGridViewRow As GridViewRow, pCellName As String) As Integer
For Each myCell As DataControlFieldCell In pGridViewRow.Cells
If myCell.ContainingField.ToString() = pCellName Then
Return Integer.Parse(myCell.Text)
End If
Next
Return Nothing
End Function
And calling the functions would look like this if it were in a class.
Dim columnNamesStringValue As String = ExtensionMethodsClassName.GetStringByCellName(pGridViewRow, "stringOfColumnName")
Dim columnNamesIntegerValue As Integer = ExtensionMethodsClassName.GetIntegerByCellName(pGridViewRow, "stringOfColumnName")
have in mind that you may not always get a value, and instead may get Nothing
Before you (perhaps try to put the value in your database), ensure it is not nothing first by checking that it is not nothing. If you wanted to insert into the database, however, it may be better to return a System.DBNull instead of Nothing from the extension methods I provided.
(DO NOT CHECK AND INSERT THE OTHER NULLS or Nothing AS DBNull'S. DIFFERENT TYPES OF NULL'S AND NOTHINGS ARE NOT EQUAL)
If (columnNamesStringValue IsNot Nothing)

Event problem inside grid view with custom paging

I want to provide custom paging in grid view.
<asp:GridView ID="gvFirst" runat="server" AutoGenerateColumns="false"
AllowPaging="true"
ondatabound="gvFirst_DataBound" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ProductID"/>
<asp:BoundField DataField="Name" HeaderText="ProductName" />
</Columns>
<PagerTemplate>
<asp:Panel ID="pnlPager" runat="server">
</asp:Panel>
</PagerTemplate>
</asp:GridView>
If I create button here and bind click event then it is fire, but problem is this event occur for each row bind with grid
protected void gvFirst_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager)
{
Panel pnPager = e.Row.FindControl("pnlPager") as Panel;
if (pnPager != null)
{
Button btnFirst = new Button();
btnFirst.Text = "1";
btnFirst.Click += new EventHandler(btnFirst_Click);
pnPager.Controls.Add(btnFirst);
}
}
}
If I create button here and bind click event then it is not fire; this event fire after all the rows bind to grid, so it will occur only once.
protected void gvFirst_DataBound(object sender, EventArgs e)
{
GridViewRow gvRow = gvFirst.BottomPagerRow;
if (gvRow != null)
{
Panel pnPager = gvRow.FindControl("pnlPager") as Panel;
if (pnPager != null)
{
Button btnFirst = new Button();
btnFirst.Text = "1";
btnFirst.Click += new EventHandler(btnFirst_Click);
pnPager.Controls.Add(btnFirst);
}
}
}
void btnFirst_Click(object sender, EventArgs e)
{
using (_NorthWindDataContext = new NorthWindDataContext())
{
var ProductInformation = from p in _NorthWindDataContext.Products
select new
{
ID = p.ProductID,
Name = p.ProductName
};
gvFirst.DataSource = ProductInformation.Skip(5).Take(5);
gvFirst.DataBind();
}
}
Another problem which I am facing is I want to provide custom paging. Now I have set page size to 5 and I am fetching 5 record from query so my grid pager is not display.
public class Productinformation
{
public int PID
{
get;
set;
}
public string PName
{
get;
set;
}
}
using (NorthWindDataContext _NorthWindDataContext = new NorthWindDataContext())
{
Proinfo = new List<Productinformation>();
Proinfo = (from p in _NorthWindDataContext.Products
select new Productinformation
{
PID = p.ProductID,
PName = p.ProductName,
}).ToList();
gvFirst.DataSource = Proinfo.Take(PageSize) ;
gvFirst.DataBind();
}
Proinfo variable declare globally.
Now when I bind I run this code it will give me error the data source does not support server-side data paging. If I use var type of variable then it is worked but we can't declare var type of variable globally, so I used it then I have to call this method every time in paging, and I don't want to use Objectdatasource.
GridView's RowCreated indeed will be called for every row in GridView, because that is the event where the GridView will (re)create the GridViewRows. But if you check for if (e.Row.RowType == DataControlRowType.Pager) there will be no overhead. This event is perfect for creating dynamic controls because it's called even on postback(as against RowDataBound). So your first way should be the correct one.
If you want to show the pager also when there are less than PageSize rows, you should force the pager to be visible e.g. in GridView's overridden OnPreRender.
GridViewRow pagerRow = (GridViewRow) this.BottomPagerRow;
if(pagerRow != null) pagerRow.Visible = true;

Resources