How to add checkbox in Asp.net Gridview in all header columns - c#

I am new in asp.net developer.
Populated a asp.net grid view with the help of data table and my all columns are dynamic.
Now i want to add a check box in my all columns dynamically bot do not want to add in rows.
One time i can check only one check box.If i am selecting second time check box in that case first selected check box should be unchecked.
My code is below:
protected void dgvWoList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (e.Row.Cells[i] != null && (!e.Row.Cells[i].IsNullOrEmpty()))
{
CheckBox chk = new CheckBox();
chk.Text = e.Row.Cells[i].Text;
e.Row.Cells[i].Controls.Add(chk);
}
}
}
}
Now i am trying to uncheck the check box but unable to do. Plz help me.
Answers:
Thanks a lot for your responses. Spl thanks AnthonyBCodes for your advise instead of check box use radio button which solved my problem. I changed my code from check box to radio button as below.
RadioButton chk = new RadioButton();
chk.GroupName = "radio";
chk.Text = e.Row.Cells[i].Text;
e.Row.Cells[i].Controls.Add(chk);

(Answered in the comments and edited into the question by the OP. Move to community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
Thanks a lot for your responses. Special thanks #AnthonyBCodes for your advice instead of a check box use a radio button which solved my problem. I changed my code from a check box to a radio button as below.
RadioButton chk = new RadioButton();
chk.GroupName = "radio";
chk.Text = e.Row.Cells[i].Text;
e.Row.Cells[i].Controls.Add(chk);

Related

How to Disable a button in dataGridView which is not clickable(c# windows application)

I found many similar questions and answers but none help me to solve my issue.
Here is a screenshot of my application where i'm facing this problem
dataGridView with buttoncell
I want to disable(or not clickable) the button if the button text says "ACCEPTED",
here is what i have and that is not working
private void Cellcontent()
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((row.Cells["Status"].Value.ToString()) == "ACCEPTED")
{
DataGridViewButtonCell cell = row.Cells["Status"] as DataGridViewButtonCell;
cell.ReadOnly = true; //if 1 cell will be disabled (not clickable)
}
}
}
I have created a small demo
https://github.com/manojsethi/DataGridViewDisableButton
Information gathered from MSDN
Hope it helps
you could do the following if you dont mind using a a different cell when the value is not ACCEPTED:
foreach (DataGridViewRow item in dataGridView1.Rows.OfType<DataGridViewRow>().Where(c => c.Cells[buttonCol.Index].Value != null && c.Cells[buttonCol.Index].Value.ToString() == "ACCEPTED"))
{
//you can replace the button with a textbox cell that contains the rejected value
item.Cells[buttonCol.Index] = new DataGridViewTextBoxCell { Value = "ACCEPTED" };
item.Cells[buttonCol.Index].ReadOnly = true;
//note that you have to make a new button cell and replace the rejected ones if the status is updated later on to be able to use the button.
}
hope this helps.

How can I get the value of a dynamically created checkbox when the submit button is clicked?

I have a asp.net page that has two controls on it, A placeholder and a submit button. During the Page_Load I create a checklist of tasks dynamically. Each row consists of a description, link to a tutorial, and a checkbox. All of the information in the row is kept in a database. If the database says the task has been checked, the code sets the checked property to true. The problem I'm having is that when the submit button is clicked I cannot find what the value is of the checked property for all of the checkboxes on the page(about 23 total).
Here is the code to create the checkboxes...
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
if (item.Attributes.Contains("ree_completed"))
checkbox.Checked = (bool)item.Attributes["ree_completed"];
checkbox.EnableViewState = true;
checkbox.ClientIDMode = System.Web.UI.ClientIDMode.Static;
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
checkbox.ID = checkboxId;
Here is the code to try and find the value of the checkbox...
foreach (Entity item in checklistCollection.Entities)
{
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
itemChecked = (bool)ViewState[checkboxId];
if (itemChecked == "true")
** update database **
//CheckBox checkbox = (CheckBox)phchecklist.FindControl(checkboxId);
}
I think I've read every post on this subject and have tried most of them. I have also read about the ViewState but the suggestions that I have read about have not worked. As you can see I also tried finding the checkbox in the controls collection by the id and that also did not work.
I do not recreate the checkboxes when posting back to the page. Some posts mention that you have to recreate the controls but when I tried to do that I received an error message saying it was a duplicate id. The other reason I would prefer not to have to recreate the page is the performance hit. The database is in a Microsoft Dynamic CRM database that is remote.
How do I retain the value of checked property across a post back?
UPDATE: I changed my logic around and fixed the duplicate id error. The page will now recreate all of the controls during the post back. I still cannot find the value of any of the checkbox controls when the submit button is clicked.
Gary
You need to provide an ID for the checkbox control when you create it. Since you are creating multiple checkboxes; one for each row in the database ... you need to add the unique row identifier to the ID. So you need to build the checkbox ID from the row ID (usually the IDENTITY). Example: ">
Then on postback while you are post-processing each row in the table, you can query the request for that specific key value pair. Something similar to this:
foreach (DataRow dr in dataTable.Rows)
Response["chk_" + dr("ID")];
Use Page Init as opossed to page_Load event. As per https://msdn.microsoft.com/en-us/library/ms178472.aspx "Use this event to read or initialize control properties"
In case for that to work you need to add an event handler to dynamically added controls
in your case
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
checkbox.CheckedChanged += checkBox_CheckedChanged;
and then what you need to do in the method
private void CheckBox_CheckedChanged(object sender, System.EventArgs e)
{
...
}
As I commented, you certainly need to create your controls during the Init event, Load is too late. Check out the asp.Net page life's cycle for details.
On a side note, you might want to let ASP.NET handle the controls's ID. You say you need to keep some value in order to get back to the database, you can wrap your checkboxes in a table. You will then be able to iterate through your controls without having to guess their names.
For instance, if your row has a HiddenField followed by your actual CheckBox:
//Please call me during Init
protected void createTheControls() {
TableRow tr;
TableCell td;
CheckBox cb;
HiddenField section, sequence;
foreach (Object item in someList)
{
section = new HiddenField();
section.Value = item.Attributes["ree_sectionnumber"].ToString();
sequence = new HiddenField;
sequence.Value = item.Attributes["ree_sequencenumber"].ToString();
cb = new CheckBox();
cb.ID = String.Concat("checkbox", (String)sequence.Value);
if (item.Attributes.Contains("ree_completed"))
cb.Checked = (bool)item.Attributes["ree_completed"];
td = new TableCell();
td.Controls.Add(section);
td.Controls.Add(sequence);
td.Controls.Add(cb);
tr = new TableRow();
tr.Cells.Add(td);
}
}
protected void readTheControls()
{
foreach (TableRow tr in myTable.Rows)
{
HiddenField section = (HiddenField)tr.Cells[0].Controls[0];
HiddenField sequence = (HiddenField)tr.Cells[0].Controls[1];
CheckBox cb = (CheckBox)tr.Cells[0].Controls[2];
}
}
I notice you try to use the ViewState explicitly, which I believe is not going to be of any help here. The solution above may look cumbersome, but it will ensure you dont need to mess with ID's when fetching the controls.
Here's a thorough explanation from MSDN, and here are a few short and sweet SO answers explaining ViewState's purpose.

How to add items (comboBox) to a tabpage - C#

its my first time using tabs and I've ran into a problem. I'm trying to make it so whenever I press a button, combo boxes will appear inside the tab that is open, and then if the button is pressed again it will add another combo box underneath the first one.
Here is how I did it:
private void buttonLevel4Add_Click(object sender, EventArgs e)
{
for (int i = 0; i < 8; i++)
{
comboBoxModuleSelect.Add(new ComboBox());
System.Drawing.Point p = new System.Drawing.Point(176, 114 + i * 25);
(comboBoxModuleSelect[i] as ComboBox).Location = p;
(comboBoxModuleSelect[i] as ComboBox).Size = new System.Drawing.Size(183, 20);
this.Controls.Add(comboBoxModuleSelect[i] as ComboBox);
}
}
But the problem is that the combo box won't be created in the tab page but underneath the tab page (i.e. on the form). Does a tab page not replace the form area? Please if someone could help I would appreciate it. Thanks
EDIT:
Oh God, another noob moment for me. I changed this line:
this.Controls.Add(comboBoxModuleSelect[i] as ComboBox);
to:
tabpage.Controls.Add(comboBoxModuleSelect[i] as ComboBox);
really sorry, I guess it just helps me to ask the question and think about it.
this.Controls.Add(comboBoxModuleSelect[i] as ComboBox);
to:
tabpage.Controls.Add(comboBoxModuleSelect[i] as ComboBox);

How to add buttons to datagridview cells not entire column

How do you add a button to cells in a row and not the entire column in a datagridview?
I think Adrian's answer was close. Try something like this.
if ((string)table.Rows[0].Cells[0].Value == "I should be a button") {
// you can add formatting or values to the button before assigning it here
table.Rows[0].cells[0] = new DataGridViewButtonCell();
}
I think the best answer if found here:
Hide gridview button. All you need to do is to add a DataGridViewButtonCell where you want buttons, and DataGridViewTextBoxCell where you do not. The column has to be DataGridViewButton type.
See this similar post in SO, probably helps
adding control to gridview
In case Win Form, Check this MSDN post
Column Types in the Windows Forms DataGridView Control
OR this code project post ... though it gives example of adding a image button
DataGridView Image Button Cell
#tmax In that case you can probably put your button creation code in GridView_RowCreated event like below
void GridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Header)
{
//Button creation code here
}
}
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
Button btn = new Button();
//btn attributes
dataGridView1.Rows[0].Cells[3].Value = new Button();
}
try something like this.
What I endded up doing was stacking a DataGridView on top of another one. I turned off the border, gridlines, and scrollbars. Then create dynamic button columns to match the main datagridview with only one row of buttons. Then I used the ColumnWidthChanged event handler to resize both the DataGridViews together. Anyway's this was my workaround for now.
DataGridViewButtonColumn dataGridViewButtonColumn = new DataGridViewButtonColumn();
dataGridViewButtonColumn.Name = "Select";
dataGridViewButtonColumn.HeaderText = "Select";
dataGridViewButtonColumn.ReadOnly = false;
dataGridView1.Columns.Add(dataGridViewButtonColumn);
After assigning data source to gridviewCTRL. you can add new column with button with below code.
DataGridViewButtonColumn startbtn = new DataGridViewButtonColumn();
startbtn.Name = "Action";
startbtn.Text = "Start";
startbtn.UseColumnTextForButtonValue=true;
int columnIndex = 6;
gridviewCTRL.Columns.Insert(columnIndex, startbtn);
This will add the button to each and every row at define column index.
if you want to render condition the AccessibleObject, then you can do something similar to below.
foreach (DataGridViewRow rowdata in gridviewCTRL.Rows)
{
// this is just an example in my case i am checking a previous column value
if (rowdata.Cells[5].Value=="XYZ")
{
rowdata.Cells[6] = new DataGridViewTextBoxCell();
}
}
This way you can dynamically render/ showing the control in the GridView in Winforms c#.
The above code simple update the cell with new cell. We can't remove button from the cell nor remove whole, so instead we can initial a new cell that will override the button visibility.
I am not sure if this will help but you can also consider using TableLayoutPanel.
Refer: Winforms TableLayoutPanel adding rows programmatically

Changing cell type in DGV from ComboBox to TextBox only works for row 0?

I have struggled all day trying to make my DataGridView behave. I'm using the following code to change a ComboBox cell to a TextBox, when user selects entry
It works beatifully for row 0, but for all other rows, the ComboBox remains on the screen, even though debugging says it's a TextBox cell! (inspecting CurrentCell).
Does anybody have a clue?
Here's a snippet:
void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
DataGridViewComboBoxEditingControl cb = sender as DataGridViewComboBoxEditingControl;
if (cb.SelectedIndex == 0 && dataGridViewReceivers.CurrentCell is DataGridViewComboBoxCell)
{
cb.SelectedIndexChanged -= new EventHandler(comboBox_SelectedIndexChanged);
dataGridViewReceivers.CellLeave -= new DataGridViewCellEventHandler(dataGridViewReceivers_CellLeave);
dataGridViewReceivers.EndEdit();
// Change to editing mode
int row = dataGridViewReceivers.CurrentCell.RowIndex;
dataGridViewReceivers[0, row] = new DataGridViewTextBoxCell();
dataGridViewReceivers[0, row].Value = "";
dataGridViewReceivers.BeginEdit(false);
dataGridViewReceivers.RefreshEdit();
dataGridViewReceivers.CellLeave += new DataGridViewCellEventHandler(dataGridViewReceivers_CellLeave);
cb.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
}
}
New rows are added using a BindingSource.AddNew().
Thanks!
EDIT:
When I call the code to replace the cell object, outside the event handler - it works! This indicates that it is worth trying a delegate...
EDIT:
Problem solved
It turns out that if I remove the focus from the DGV during the replacement, it works! Simply momentarily setting the focus to a button, and back again does the trick!
For some reason, the DGV does not allow me to change the cell type when it has focus. Unselecting the cell is not enough - focus needs to be removed from the control.
This looks like a .NET bug!...

Categories