i have my gridviews itemtemplate tag
<asp:TemplateField HeaderText="TotalTime" SortExpression="TotalTime">
<ItemTemplate>
<asp:TextBox ID="TotalTime" readonly="true" runat="server" ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
on my button click event i am trying to make the textbox readonly property to false and get the value , but it doesnt work for TotalTime textbox
protected void BtnSaveAttendence_Click(object sender, EventArgs e)
{
foreach (GridViewRow Gr in GridView1.Rows)
{
TextBox txt = (TextBox)(Gr.FindControl("TotalTime"));
txt.ReadOnly = false;
}
int Rest = new int();
object[] objAttnd = new object[8];
foreach (GridViewRow GR in GridView1.Rows)
{
objAttnd[0] = 0;
objAttnd[1] = ((Label)GR.FindControl("LblEMPNAME")).Text;
objAttnd[2] = UserInfo.Company.CompanyID;
objAttnd[3] = Common.Convert_MM_DD_YYYY(txtDate1.Text);
objAttnd[4] =((TextBox)GR.FindControl("InTime")).Text;
objAttnd[5] =((TextBox)GR.FindControl("OutTime")).Text;
objAttnd[6] = ((TextBox)GR.FindControl("TotalTime")).Text;
objAttnd[7] = Convert.ToDecimal(((Label)GR.FindControl("LblEmpCode")).Text);
foreach (GridViewRow Gr in GridView1.Rows)
{
TextBox txt = (TextBox)(Gr.FindControl("TotalTime"));
txt.ReadOnly = true;
}
Rest = objAttendance.InsertUpdateAttendenceDetailNew(objAttnd);
}
if (Rest == -1)
{
lblError.Text = "<div class='ErrorMsg'> Attendance details already added for Selected date !!</div>";
}
}
Plz tell me how to get the value
As far as Your code it will read only one value of the Textbox as you are making it Readonly false and reading value in the Foreach loop then inside that Foreach loop itself you are having another Foreach loop that finds the Textbox and makes Readonly true so take that ForEach loop out and alter your code like,
protected void BtnSaveAttendence_Click(object sender, EventArgs e)
{
foreach (GridViewRow Gr in GridView1.Rows)
{
TextBox txt = (TextBox)(Gr.FindControl("TotalTime"));
txt.ReadOnly = false;
}
int Rest = new int();
object[] objAttnd = new object[8];
foreach (GridViewRow GR in GridView1.Rows)
{
objAttnd[0] = 0;
objAttnd[1] = ((Label)GR.FindControl("LblEMPNAME")).Text;
objAttnd[2] = UserInfo.Company.CompanyID;
objAttnd[3] = Common.Convert_MM_DD_YYYY(txtDate1.Text);
objAttnd[4] =((TextBox)GR.FindControl("InTime")).Text;
objAttnd[5] =((TextBox)GR.FindControl("OutTime")).Text;
objAttnd[6] = ((TextBox)GR.FindControl("TotalTime")).Text;
objAttnd[7] = Convert.ToDecimal(((Label)GR.FindControl("LblEmpCode")).Text);
/*ForEach from Here to*/
Rest = objAttendance.InsertUpdateAttendenceDetailNew(objAttnd);
}
/*===>here*/
foreach (GridViewRow Gr in GridView1.Rows)
{
TextBox txt = (TextBox)(Gr.FindControl("TotalTime"));
txt.ReadOnly = true;
}
if (Rest == -1)
{
lblError.Text = "<div class='ErrorMsg'> Attendance details already added for Selected date !!</div>";
}
}
Try adding readonly attribute from code behind like below:
TotalTime.Attributes.Add("readonly", "readonly");
And no need to set readonly to false before reading its value in code behind.
Related
I am trying to reference a non-asp check box in C# code behind. The reason the checkbox is not an asp element, is it gets auto-generated on the fly, rather than being a part of the website. So far I have the following relevant aspx:
<asp:Table ID="myTable" runat="server" Width="100%">
<asp:TableRow>
<asp:TableCell>A</asp:TableCell>
<asp:TableCell>B</asp:TableCell>
<asp:TableCell>C</asp:TableCell>
<asp:TableCell>D</asp:TableCell>
<asp:TableCell>E</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:LinkButton runat="server" ID="TEST" CssClass="btn btn-default pull-right" OnClick="TEST_Click">
TEST <i class="m-icon-swapright m-icon-white"></i>
</asp:LinkButton>
And the C# code behind is:
public void GenerateTable()
{
int i = 0;
bool[] box = {true, false, true, false, true};
List<TableRow> tRows = new List<TableRow>();
TableRow newRow = new TableRow();
tRows.Add(newRow);
foreach (var check in box)
{
TableCell tempCell = new TableCell();
if (check)
{
tempCell.Text = "<input type=\"checkbox\" id=\"chk" + i + "\" >";
}
else
{
tempCell.Text = "<input type=\"checkbox\" id=\"chk" + i + "\" checked>";
}
tRows[0].Cells.Add(tempCell);
i++;
}
foreach (TableRow row in tRows)
{
myTable.Rows.Add(row);
}
}
public void TEST_Click(object sender, EventArgs e)
{
HtmlInputCheckBox chkbox = (HtmlInputCheckBox)FindControl("chk1");
if (chkbox != null)
{
if (!chkbox.Checked)
{
MessageBox.Show("Checked");
}
else
{
MessageBox.Show("NOT Checked");
}
}
else
MessageBox.Show("NOTHING :(");
}
chkbox is always null :(.
You'll need to change two things.
In order to find a checkbox via FindControl it must be part of the pages control collection, which means you have to add a CheckBoxcontrol.
CheckBox c = new CheckBox { ID = "chk" + i };
tempCell.Controls.Add(c);
The dynamically added CheckBox control is part of the control collection of the Table, so you'll have to search for it there instead of on the page.
CheckBox chkbox = (CheckBox)this.myTable.FindControl("chk1");
Below you find a full update of your code.
protected void Page_Load(object sender, EventArgs e)
{
GenerateTable();
}
public void GenerateTable()
{
int i = 0;
bool[] box = {true, false, true, false, true};
List<TableRow> tRows = new List<TableRow>();
TableRow newRow = new TableRow();
tRows.Add(newRow);
foreach (var check in box)
{
TableCell tempCell = new TableCell();
CheckBox c = new CheckBox { ID = "chk" + i };
c.Checked = check;
tempCell.Controls.Add(c);
tRows[0].Cells.Add(tempCell);
i++;
}
foreach (TableRow row in tRows)
{
myTable.Rows.Add(row);
}
}
public void TEST_Click(object sender, EventArgs e)
{
CheckBox chkbox = (CheckBox)this.myTable.FindControl("chk1");
if (chkbox != null)
{
if (!chkbox.Checked)
{
MessageBox.Show("Checked");
}
else
{
MessageBox.Show("NOT Checked");
}
}
else
{
MessageBox.Show("NOTHING :(");
}
}
This is my code
foreach (GridViewRow row in GridView1.Rows)
{
dataReader.Read();
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox cb = new CheckBox();
cb.ID = "chkbox";
if (int.Parse(dataReader[0].ToString()) == 0)
cb.Checked = false;
else
cb.Checked = true;
cb.CheckedChanged += new EventHandler(chkBoxChange);
row.Cells[4].Controls.Add(cb);
}
}
But even though I had written:
cb.CheckedChanged += new EventHandler(chkBoxChange);
the function
public void chkBoxChange(object sender, EventArgs e)
{
}
is not invoking when I checked the CheckBox.
[ Tested Code ]
You can use below code in OnRowCreated and OnRowDataBound events of GridView.
This way will successfully invoke the CheckedChanged event of dynamically created CheckBox.
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox cb = e.Row.Cells[4].FindControl("chkbox") as CheckBox;
if (cb == null)
{
cb = new CheckBox();
cb.ID = "chkbox";
cb.AutoPostBack = true;
cb.CheckedChanged += new EventHandler(chkBoxChange);
e.Row.Cells[4].Controls.Add(cb);
}
}
I need to generate columns which contains checkbox based on data stored in database (this grid can have different number of columns per month)
I've got this code with custom template on my grid view control:
aspx part:
<asp:Button runat="server" ID="bt_save_top" OnClick="bt_save_Click" Text="Save" />
<asp:GridView runat="server" ID="gv_result" AutoGenerateColumns="false" BorderStyle="Solid" BorderWidth="1" RowStyle-BorderWidth="1" RowStyle-BorderStyle="Solid">
</asp:GridView>
*cs :
protected void Page_Load(object sender, EventArgs e)
{
var ds = new DataSet();//getting data from database
var weekDayColumns = GenerateColumns(ds);
foreach (DataControlField dataControlField in weekDayColumns)
{
gv_result_tw.Columns.Add(dataControlField);
}
gv_result_tw.DataSource = ds.Tables[0];
gv_result_tw.DataBind();
}
private DataControlFieldCollection GenerateColumns(DataSet dsTable)
{
var columns = new DataControlFieldCollection();
foreach (DataColumn column in dsTable.Tables[0].Columns)
{
var itemTemplate = new TemplateField
{
HeaderText = column.Caption,
ControlStyle =
{
CssClass = "gv_row"
},
HeaderStyle =
{
CssClass = "gv_row"
},
ItemTemplate = new CustomItemTemplate(ListItemType.Item, column.ColumnName)
};
columns.Add(itemTemplate);
}
return columns;
}
protected void bt_save_Click(object sender, EventArgs e)
{
foreach(var row in gv_result_tw.Rows)
{
var columnNameField = gvr.FindControl("hidden_time") as HiddenField;
// Here i'm getting always null
}
}
CustomItemTemplate.cs
public class CustomItemTemplate : ITemplate
{
private readonly ListItemType _type;
private readonly string _columnName;
public ItemTemplateGenerator(ListItemType t, string columnName)
{
_type = t;
_columnName = columnName;
}
// Override InstantiateIn() method
void ITemplate.InstantiateIn(Control container)
{
switch (_type)
{
case ListItemType.Item:
var visibleCheckbox = new CheckBox
{
ID = $"chb_{_columnName.Replace(":", "_")}_visible"
};
visibleCheckbox.DataBinding += VisibleCheckbox_DataBinding;
var invisibleField = new HiddenField
{
ID = $"chb_{_columnName.Replace(":", "_")}_invisible"
};
var hiddenInput = new HiddenField
{
ID = $"hidden_time",
Value = _columnName
};
container.Controls.Clear();
container.Controls.Add(hiddenInput);
container.Controls.Add(visibleCheckbox);
container.Controls.Add(invisibleField);
break;
}
}
// The DataBinding event of your controls
private void VisibleCheckbox_DataBinding(object sender, EventArgs e)
{
var checkBox = (CheckBox)sender;
var container = (GridViewRow)checkBox.NamingContainer;
var hiddenField = (HiddenField)checkBox.NamingContainer.FindControl($"chb_{_columnName.Replace(":","_")}_invisible");
var bindValue = DataBinder.Eval(container.DataItem, _columnName);
// Adding check in case Column allows null values
if (bindValue != DBNull.Value)
{
hiddenField.Value = bindValue.ToString();
checkBox.Checked = bindValue.ToString() == "1";
}
}
}
So the question is how I should done this "FindControl" to get proper field instead of null?
If you need more details please just ask.
You have to make two changes, one in the InstantiateIn implementation of your CustomItemTemplate so the container gets an ID as well. In this case I picked the value of _columnName:
public class CustomItemTemplate : ITemplate
{
// stuff omitted for brevity
// Override InstantiateIn() method
void ITemplate.InstantiateIn(Control container)
{
// set the ID of the container these fields are in!
container.ID = _columnName;
// rest of your code
// make sure hidden_time is still unique!
var hiddenInput = new HiddenField
{
ID = $"{_columnName.Replace(":", "_")}_hidden_time",
Value = _columnName
};
}
}
Then your button click implementation can leverage that ID when it sets off to find the control:
protected void bt_save_Click(object sender, EventArgs e)
{
// a GridViewRow has cells ...
foreach (GridViewRow row in gv_result_tw.Rows)
{
// ... the cells are of type DataControlFieldCell
foreach (DataControlFieldCell col in row.Cells)
{
// ... but we get some bonus fields as well
if (col.Controls.Count > 0)
{
// .. if we skip those
// ... we get a cell that has its ID set to the value
// that was used to generate the ID of the hiddenfield
var columnNameField = row.FindControl(col.ID + "_hidden_time") as HiddenField;
// columnNameField will not be null now ...
}
}
}
}
I have an aspx page where I dynamically create checkboxes and add them to a panel from data in a SQL database. I need to have only one checkbox checked at a time. I have tried and googled just about everything but I cannot get the right answer. How would I go about getting that done.
My code for creating the checkboxes
public void CreateTimeSelection()
{
DataSet times = GetTimes();
int i = 0;
foreach (DataTable table in times.Tables)
{
foreach (DataRow row in table.Rows)
{
CheckBox chkTime = new CheckBox();
i += 1;
chkTime.ID = row["Time"].ToString();
chkTime.AutoPostBack = true;
chkTime.Text = row["Time"].ToString();
chkTime.CheckedChanged += new EventHandler(this.CheckChanged_click);
pnlTimeSlots.Controls.Add(chkTime);
pnlTimeSlots.Controls.Add(new LiteralControl("<br />"));
}
}
}
Code for Checkbox event handlers
protected void CheckChanged_click(object sender, EventArgs e)
{
CheckBox chkSelect = (CheckBox)sender;
if (chkSelect.Checked == true)
{
//set other checkboxes to false
}
}
I want to bind my grid column header names by retrieving data from a table. This table has two fields, DomainID and DomainName, I want to display the DomainNames as Column header of the Grid.
Actually I am creating employee grid view. I want all the domain names of employee to be displayed as a header and i have to check the corresponding domain in Checkbox.
Please Give me some ideas.
Thanks in advance.
From what i understood....
Make a grid view
Create two columns:
a. TextBoxColumn
b. CheckBoxColumn
Set your column header using .HeaderText property
Add the columns to your data grid view
Query your database and get the data_table from it
using dgv.DataSource = data_table bind your data to the table
OR
Make a for loop for all rows in the data_table and add each row explicitly
For getting your checkboxes to work, handle the cellContentClick event of the data grid view and perform the necessary updates in your database.....
Hope it helps....
You could load the headers into a DataTable and then create them dynamically with a custom TemplateField.
Here's the aspx part:
<asp:GridView ID="GridView1" AutoGenerateColumns="false" DataKeyNames="EmployeeID" runat="server" >
<SelectedRowStyle BackColor="Aqua" />
<Columns>
<asp:TemplateField HeaderText="Employee" SortExpression="Employee">
<ItemTemplate>
<asp:HiddenField ID="HiddenEmpID" Value='<%# Bind("EmployeeID") %>' runat="server" />
<asp:label runat="server" ID="LblEmployee" Text='<%# Bind("EmployeeName") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="BtnSave" Text="Save" runat="server" onclick="BtnSave_Click" />
Here's a complete sample:
public partial class GridTest : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
CreateGridColumns();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BindGrid();
}
private void CreateGridColumns()
{
var tblDomain = GetDomains();
// Create dynamic TemplateFields
foreach (DataRow row in tblDomain.Rows)
{
String domainName = row.Field<String>("DomainName");
TemplateField field = new TemplateField();
//Initalize the DataField value.
field.ItemTemplate = new GridViewCheckBoxTemplate(ListItemType.Item, domaninName);
field.HeaderText = domainName;
//Add the newly created field to the GridView.
GridView1.Columns.Add(field);
}
}
private DataTable GetDomains()
{
var tblDomain = new DataTable();
tblDomain.Columns.Add("DomainID", typeof(int));
tblDomain.Columns.Add("DomainName");
tblDomain.Rows.Add(1, "Google.com");
tblDomain.Rows.Add(2, "Yahoo.com");
tblDomain.Rows.Add(3, "Msn.com");
tblDomain.Rows.Add(4, "Youtube.com");
tblDomain.Rows.Add(5, "Myspace.com");
tblDomain.Rows.Add(6, "Facebook.com");
tblDomain.Rows.Add(7, "Wikipedia.org");
return tblDomain;
}
private void BindGrid()
{
var tblDomain = GetDomains(); // load domains from database or wherever
var tblData = new DataTable();// load sample data
tblData.Columns.Add("EmployeeID", typeof(int));
tblData.Columns.Add("EmployeeName");
//add domains as DataTable-Columns
foreach (DataRow row in tblDomain.Rows)
{
String domaninName = row.Field<String>("DomainName");
//Add column from domain-name
tblData.Columns.Add(domaninName, typeof(bool)); //CheckBox-Checked is a boolean
}
//get some Employees and random checked state
var rnd = new Random();
var empRow = tblData.NewRow();
empRow["EmployeeID"] = 1;
empRow["EmployeeName"] = "Jon";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
empRow = tblData.NewRow();
empRow["EmployeeID"] = 2;
empRow["EmployeeName"] = "Eric";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
empRow = tblData.NewRow();
empRow["EmployeeID"] = 3;
empRow["EmployeeName"] = "Alain";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
GridView1.DataSource = tblData;
GridView1.DataBind();
}
// show how to retrieve all checkbox values and the according EmployeeID
protected void BtnSave_Click(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 0) return;
var checkBoxColumns = GridView1.Columns.Cast<DataControlField>()
.Select((bf,index) => new{Field=bf, Index=index})
.Where(f => f.Field.GetType() == typeof(TemplateField) && ((TemplateField)f.Field).ItemTemplate.GetType() == typeof(GridViewCheckBoxTemplate))
.ToArray();
foreach (GridViewRow row in GridView1.Rows)
{
int EmployeeID = int.Parse(((HiddenField)row.FindControl("HiddenEmpID")).Value);
foreach (var f in checkBoxColumns)
{
String domain = f.Field.HeaderText;
bool isChecked = row.Controls[f.Index].Controls.OfType<CheckBox>().First().Checked;
}
}
}
}
Here's the custom ITemplate:
public class GridViewCheckBoxTemplate : ITemplate
{
ListItemType _templateType;
string _columnName;
public GridViewCheckBoxTemplate(ListItemType type, string colname)
{
_templateType = type;
_columnName = colname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_templateType)
{
case ListItemType.Header:
break;
case ListItemType.Item:
var chb1 = new CheckBox();
chb1.DataBinding += new EventHandler(CB_DataBinding);
container.Controls.Add(chb1);
break;
case ListItemType.EditItem:
//As, I am not using any EditItem, I didnot added any code here.
break;
case ListItemType.Footer:
break;
}
}
void CB_DataBinding(object sender, EventArgs e)
{
CheckBox chb = (CheckBox)sender;
GridViewRow container = (GridViewRow)chb.NamingContainer;
object dataValue = ((DataRowView)container.DataItem)[_columnName];
chb.Checked = dataValue != DBNull.Value && (bool)dataValue;
}
}