Integer only validation for dynamically added Textbox inside Asp.net Gridview - c#

Below is how my GridView code , since the datatable is a pivoted value so the number of columns cannot be predicted. So I am adding textbox dynamically through code.
<asp:GridView ID="gvData"
EmptyDataText="There are no data records to display."
runat="server" AutoGenerateColumns="false"
HeaderStyle-BackColor="#3AC0F2"
HeaderStyle-ForeColor="White" OnRowDataBound="gvData_RowDataBound" >
<RowStyle BorderColor="LightBlue" />
</asp:GridView>
protected void Page_Load(object sender, EventArgs e)
{
foreach (var item in columnNames)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = item;
gvData.Columns.Add(tfield);
}
gvData.DataSource = ds.Tables[0];
gvData.DataBind();}
protected void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 3; i < columnNames.Length; i++)
{
TextboxCount++;
TextBox txtName = new TextBox();
txtName.ID = "txt" + Convert.ToString(TextboxCount);
txtName.BorderStyle = BorderStyle.None;
txtName.Text = (e.Row.DataItem as DataRowView).Row[columnNames[i]].ToString();
e.Row.Cells[i].Controls.Add(txtName); }}}
Now when user try to change value in the textbox I have to validate that they only enter integer value.
Here I am not sure what has to be done.

You can use int.TyrParse method
Example
int number;
string s = "AA";
bool IsInteger = int.TryParse(s, out number);

You could use javascript function and that to textbox from code behind like:
// Add this gvData_RowDataBound , allownumbers is a javascript function
txtName.Attributes.Add("onkeypress", "javascript:return allownumbers(event);");
Or else if you are using .NET 4.5 version then try out this:
txtName.Attributes["type"] = "number";

Related

DataGrid View Multicolored Cell Text

I was looking to see if it was possible to create multicolored cell text in an asp.net DataGrid View. The project that I'm working on contains a cell that has info related to the status of a unit which has the values of Unit1--DP, Unit2--ER, Unit3--ON and a couple others and I want to chance the color of each based on if it says AV, DP, ER, or ON. The ideal would be to color AV as Green, DP as Orange, ER as Yellow, and ON as Red.
Any information on how to do this would be helpful as there isn't much information as to if this is possible currently available.
Ok, for a listview, Gridview, Repeater, and datalist?
The place for doing formating of the data (or grid) display is the DataBound event. (or ItemDataBound event).
This lets you see/grab/use/change/format the one row of data for each "repeated" item.
So, if I have a list of hotels, and say for a given city, I could color it blue like this:
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) |
(e.Item.ItemType == ListItemType.AlternatingItem)) {
TextBox txtCity = e.Item.FindControl("City") as TextBox;
if (txtCity.Text == "Edmonton")
{
// set background as blue
txtCity.BackColor = System.Drawing.Color.LightSkyBlue;
}
}
}
So, in your case, you could grab that control (find control), and then based on the text that follows the --, then you could color/set the background of that given control.
So, something close to this :
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) |
(e.Item.ItemType == ListItemType.AlternatingItem)) {
TextBox txtCity = e.Item.FindControl("City") as TextBox;
string[] strSufix = txtCity.Text.Split(new string[] { "--" },StringSplitOptions.None);
if (strSufix[1] == "AV")
txtCity.BackColor = System.Drawing.Color.LightGreen;
if (strSufix[1] == "DP")
txtCity.BackColor = System.Drawing.Color.Orange;
if (strSufix[1] == "ER")
txtCity.BackColor = System.Drawing.Color.Yellow;
if (strSufix[1] == "ON")
txtCity.BackColor = System.Drawing.Color.Red;
}
}
Edit: So user has gridview, and multiple items per cell.
So, say this markup:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false" CssClass="table" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
<asp:BoundField DataField="Test" HeaderText="Test" ItemStyle-Width="270" />
</Columns>
</asp:GridView>
Ok, and our code to load is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
DataTable rstData = new DataTable();
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And now we get this:
so, as suggested, we add/use the Row data bound for such formatting.
So, we can use some code say like this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// format 5th cell (cell 4)
string celltext = e.Row.Cells[4].Text;
string OcellText = celltext; // save orginal fomat (with spaces)
if (celltext.Contains("--"))
{
celltext = celltext.Replace(" ", ""); // trim blanks
string[] Tokens = celltext.Split(',');
foreach (string OneThing in Tokens)
{
if (OneThing.Contains("--"))
{
string[] sufux = OneThing.Split(new string[] { "--" },StringSplitOptions.None);
if (sufux[1] == "AV")
OcellText = MyFormat(OcellText, OneThing, "LightGreen");
if (sufux[1] == "ON")
OcellText = MyFormat(OcellText, OneThing, "Red");
}
}
e.Row.Cells[4].Text = OcellText;
}
}
}
string MyFormat(string Source, string sFind, string MyColor)
{
string sHTML = #"<span style=background-color:" + MyColor + ">" + sFind + "</span>";
string MyResult = Source.Replace(sFind, sHTML);
return MyResult;
}
Now, when we run this, we get this:

Not able to access dynamically generated templated field controls

I am creating dynamic Template Fields for my gridview:
<asp:GridView ID="grdData" runat="server" DataKeyNames = "ID" AutoGenerateColumns="false" OnRowDataBound="grdData_RowDataBound">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkAll" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="editbtn" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
the code to add templateField is below:
private void BindGridView(DataTable dtData)
{
foreach (DataColumn item in dtData.Columns)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = item.ToString();
grdData.Columns.Add(tfield);
}
grdData.DataSource = dtData;
ViewState["dtDataTable"] = dtData;
grdData.DataBind();
}
and in row databound I am adding textbox and label to the templatefield:
protected void grdData_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataTable dtData = (DataTable)ViewState["dtDataTable"];
if (e.Row.RowType == DataControlRowType.DataRow)
{
int i = 1;
foreach (DataColumn item in dtData.Columns )
{
TextBox txtBox = new TextBox();
txtBox.ID = "txt"+item.ToString();
txtBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
txtBox.Visible = false;
e.Row.Cells[i].Controls.Add(txtBox);
Label lblBox = new Label();
lblBox.ID = "lbl" + item.ToString();
lblBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
e.Row.Cells[i].Controls.Add(lblBox);
i++;
}
}
}
Everything is working good so far,The grid is getting created and the values are getting populated ,but when i am calling below method and try to access the gridview control ,its throwing object reference error:
protected void OnCheckedChanged(object sender, EventArgs e)
{
bool isUpdateVisible = false;
CheckBox chk = (sender as CheckBox);
if (chk.ID == "chkAll")
{
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked = chk.Checked;
}
}
}
CheckBox chkAll = (grdData.HeaderRow.FindControl("chkAll") as CheckBox);
chkAll.Checked = true;
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked;
for (int i = 1; i < row.Cells.Count; i++)
{
Label test= row.FindControl("lblName") as Label;//this is coming null
Below code lines are throwing object reference error as they are not able to find control
row.Cells[i].Controls.OfType<Label>().FirstOrDefault().Visible = !isChecked;//this line throwing object reference error
if (row.Cells[i].Controls.OfType<TextBox>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<TextBox>().FirstOrDefault().Visible = isChecked;
}
if (row.Cells[i].Controls.OfType<DropDownList>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<DropDownList>().FirstOrDefault().Visible = isChecked;
}
if (isChecked && !isUpdateVisible)
{
isUpdateVisible = true;
}
if (!isChecked)
{
chkAll.Checked = false;
}
}
}
}
btnUpdate.Visible = isUpdateVisible;
}
Edit:
I tried reinistialising the controls in preinit event but still no luck:
protected void Page_PreInit(object sender, EventArgs e)
{
if (ViewState["gridData"] != null)
{
BindGridView((DataTable)ViewState["gridData"]);
}
}
What I am doing wrong?
I recreated the dynamic gridview Controls in OnRowCreated as this event gets called in every postback instead of onRowDataBound Event and it worked like charm.

Use textbox in gridview bound field in asp.net

I have a gridview which I used to display tabular data.
I want the users to edit the field values and save it.
Is there any way to add a textbox in place of bound field.
This is my gridview.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="186px" Width="325px">
<Columns>
</Columns>
</asp:GridView>
This is the code behind which populate the GridView
public List<DataControlField> columns = new List<DataControlField>();
public object DataSource { get; set; }
protected void Page_Init(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
BoundField bf = new BoundField() ;
bf.HeaderText = "LastName" ;
bf.DataField = "LastName";
columns.Add(bf);
}
foreach (DataControlField col in columns)
{
GridView1.Columns.Add(col);
}
}
protected void Page_Load(object sender, EventArgs e)
{
List<Data> lastN = new List<Data>() ;
for(int i = 0 ; i < 50; i++ )
{
lastN.Add(new Data(i.ToString()));
}
GridView1.DataSource = lastN;
GridView1.DataBind();
}
}
I would like to suggest you to try listview, it allows you to edit the dynamic data, such as the content in textbox
You can use a GridView with EditTemplates. You can refer to this example for that.
It is possible to edit all rows of a GridView at the same time. Refer to this example.
You can optionally use Telerik's ASP.NET Data Grid that you can configure to work like excel using this example.

Gridview EditItemTemplate DropDownList Get SelectedValue

In my Gridview I have the following template field:
<asp:TemplateField HeaderText="Dept Code" SortExpression="DeptCode">
<ItemTemplate>
<%# Eval("DeptCode") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlDeptCode" runat="server"
SelectedValue='<%# Eval("DeptCode") %>'
DataSource='<%# GetAllDepartments() %>'
DataTextField="DeptCode"
DataValueField="DeptCode" />
</EditItemTemplate>
</asp:TemplateField>
This works great when I click Edit on a row it populates the DropDownList with all values and selects the correct value for that row.
However, when I try to update the row: OnRowUpdating="UpdateRow"
protected void UpdateRow(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = UserGV.Rows[e.RowIndex];
DropDownList ddl = row.FindControl("ddlDeptCode") as DropDownList;
string deptCode = ddl.SelectedValue;
}
It finds the DropDownList control but the SelectedValue is always an empty string.
I need access to the selected value to save to the database.
Any ideas as to how I can get the SelectedValue of a DropDownList in a Gridview in code behind?
Edit:
You can also populate the DropDownList and SelectedValue from the code behind:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
var deptMgr = new DepartmentMgr();
List<Department> departments = deptMgr.GetAllDepartments();
DropDownList ddList = (DropDownList)e.Row.FindControl("ddlDeptCode");
ddList.DataSource = departments;
ddList.DataTextField = "DeptCode";
ddList.DataValueField = "DeptCode";
ddList.DataBind();
string userDeptCode = DataBinder.Eval(e.Row.DataItem, "DeptCode").ToString();
ddList.SelectedItem.Text = userDeptCode;
ddList.SelectedValue = userDeptCode;
}
}
}
I was using a bit of a hack to get a second header for the table title when binding the gridview:
GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
TableCell th = new TableHeaderCell();
th.HorizontalAlign = HorizontalAlign.Center;
th.ColumnSpan = UserGV.Columns.Count;
th.BackColor = Color.SteelBlue;
th.ForeColor = Color.White;
th.Font.Bold = true;
th.Text = "Manage Users";
row.Cells.Add(th);
InnerTable.Rows.AddAt(0, row);
I don't completely understand how this was interfering with getting the SelectedValue of a DropDownList control but as soon as I commented that out it started working.
For those interested I got the second header working with this using a different approach:
In the .aspx file I added this to the Gridview:
OnRowCreated="CreateRow"
And in the code behind I added the following method:
protected void CreateRow(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView gridView = (GridView)sender;
GridViewRow row = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal);
TableCell th = new TableHeaderCell();
th.HorizontalAlign = HorizontalAlign.Center;
th.ColumnSpan = UserGV.Columns.Count;
th.ForeColor = Color.White;
th.BackColor = Color.SteelBlue;
th.Font.Bold = true;
th.Text = "Manage Users";
row.Cells.Add(th);
gridView.Controls[0].Controls.AddAt(0, row);
}
}
Everything is working correctly now.
In the edit template, set the selectedvalue from the data bindings, then you will get the correct selected value instead of a null.
SelectedValue='<%# Bind("DeptCode") %>'

Dropdown list default value on button click

I'm working on an asp project. I have a situation where I need to search files and display in gridview. The gridview have three drop down list, my problem now is how can I show the default value of my dropdown based on the result set returned when I click the search button, since I already set the default value of the drop down ("Please Select") on data row bound. Because at first load my drop down should show "please select" value. Thanks a lot for the help. below is my code.
protected void btnSearch_Click(object sender, EventArgs e)
{
int uFlag = 0;
string uploadFlag = this.ddlUploadDate.SelectedValue;
string fileName = this.txtSearchText.Text;
string uploadDt = this.txtDate.Text;
string status = this.ddlStatus.SelectedValue.ToString();
List<EventFile> fileSearch = new List<EventFile>();
fileSearch = CoMailAssociationDAL.SearchFile(uFlag, fileName, uploadDt, status);
gvwAssociation.DataSource = fileSearch;
gvwAssociation.DataBind();
}
protected void gvwAssociation_RowDataBound(object sender, GridViewRowEventArgs e)
{
ListItem Item = new ListItem();
Item.Text = "Please Select";
Item.Value = "0";
Item.Selected = true;
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlpool = (DropDownList)e.Row.FindControl("ddlpool");
DropDownList ddlyear = (DropDownList)e.Row.FindControl("ddlyear");
DropDownList ddlevent = (DropDownList)e.Row.FindControl("ddlevent");
ddlpool.DataSource = CoMailAssociationDAL.GetCoBindEvents();
ddlpool.DataBind();
ddlpool.Items.Insert(0, Item);
ddlevent.DataSource = CoMailAssociationDAL.GetCoBindEvents();
ddlevent.DataBind();
ddlevent.Items.Insert(0, Item);
for (int intCount = 2013; intCount <= 2020; intCount++)
{
ddlyear.Items.Add(intCount.ToString());
ddlyear.SelectedIndex = 1;
}
}
}
You can do it by creating a condition in your grid RowDataBound event by taking one hiddenfield in itemtemplate for value from database and find that as
for (int intCount = 2013; intCount <= 2020; intCount++)
{
ddlyear.Items.Add(intCount.ToString());
HiddenField result= GridView1.Rows[e.RowIndex].FindControl("hdnpool") as HiddenField;
if(result!=null)
ddlyear.SelectedIndex =result.value;
else
ddlyear.SelectedIndex = 1;
}
In grid please use below for each dropdown:
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="ddpool" runat="server"></asp:DropDownList>
<asp:HiddenField ID="hdnpool" Value="<%# Eval("PoolColumninDB") %>" runat="server"></asp:HiddenField>
</ItemTemplate>
</asp:TemplateField>
Have you try this
for (int intCount = 2013; intCount <= 2020; intCount++)
{
ddlyear.Items.Add(intCount.ToString());
ddlyear.SelectedValue= 1;
}

Categories

Resources