I created these checkboxes in my gridview to allows my users to select several rows. My problem is when the checkboxes are clicked they are suppose to store info for each one clicked. I placed breakpoints inside and the event is never triggered. Is this something I need to call in order to have this event run? I was under the impression it was like any other event where it just ran upon triggering it. I haven't found a generic help for these type of issue, it seems to be more specific problems. Do you have nay reference to help or any suggestions on how to allow my event to trigger properly?
On form load this is established
ckBox = new CheckBox();
//Get the column header cell bounds
Rectangle rect = this.dropdeadGridView.GetCellDisplayRectangle(0, -1, true);
ckBox.Size = new Size(18, 18);
//Change the location of the CheckBox to make it stay on the header
ckBox.Location = rect.Location;
ckBox.CheckedChanged += new EventHandler(ckBox_CheckedChanged);
//Add the CheckBox into the DataGridView
this.dropdeadGridView.Controls.Add(ckBox);
Then this is where I declare what happens in the chkbox_CheckChanged Event
var rows = dropdeadGridView.Rows;
for (int j = 0; j < this.dropdeadGridView.RowCount; j++)
{
this.dropdeadGridView[0, j].Value = this.ckBox.Checked;
bool checkBoxValue = Convert.ToBoolean(dropdeadGridView.Rows[5].Cells[1].Value);
if (checkBoxValue)
{
values += rows[j].Cells[2] + ",";
CurrentOrders = values;
}
}
this.dropdeadGridView.EndEdit();
Hope you are using a windows application
http://csharp.net-informations.com/datagridview/csharp-datagridview-checkbox.htm
this link is telling how to add checkboxes in gridview. When changing selection the grids events like afteredit,validateedit etc will fire.
We are coding at there by checking the column number(if the column number matches with check box column number) do the operations which you mentioned in event at there
I'm less experianced in winforms and i used C1FlexGrid only(Equivalent will be there in windows grid also)
Add an unhook event call, before hooking the event.
ckBox.CheckedChanged -= new EventHandler(ckBox_CheckedChanged);
Mostly your problem will get solved
Related
Has C# indexed control arrays or not? I would like to put a "button array" for example with 5 buttons which use just one event handler which handles the index of all this 5 controls (like VB6 does). Else I have to write for each of these 5 buttons one extra event handler. And if I have 100 buttons, I need 100 event handlers? I mean something like that:
TextBox1[i].Text="Example";
It could make coding definitely easier for me to work with control arrays. Now I have seen, that C# at least has no visible array functionality on user controls and no "index" property on the user controls. So I guess C# has no control arrays, or I must each element call by known name.
Instead of giving 100 TextBoxes in a for loop 100 incrementing values, I have to write:
TextBox1.Text = Value1;
TextBox2.Text = Value2;
...
...
TextBox100.Text = Value100;
A lot of more work + all these 100 event handlers each for one additional TextBox extra.
I know I'm a little late to this party, but this solution will work:
Make a global array:
TextBox[] myTextBox;
Then in your object's constructor, after the call to
InitializeComponent();
initialize your array:
myTextBox = new TextBox[] {TextBox1, TextBox2, ... };
Now you can iterate your array of controls:
for(int i = 0; i < myTextBox.Length; i++)
myTextBox[i].Text = "OMG IT WORKS!!!";
I hope this helps!
Pete
As I mentioned in comment to a solution by HatSoft, C# Winforms does not allow you to create control arrays like old VB6 allowed us. The nearest I think we can get to is what HatSoft and Bert Evans in their posts have shown.
One thing that I hope would satisfy your requirement is the event handler, you get a common event handler and in the event handler when you typecast the "sender" you get the control directly just like you would in VB6
C#
TextBox textBox = sender as TextBox;
VB6
TextBox textBox = TextBox1[i];
So the only trouble you might have is wiring those 100 TextBoxes to a single event handler, if you are not creating the controls dynamically through code rather creating it manually at design time then all one can suggest is group them in a container like say Panel. Then on Form Load wire them all up to a single event handler like this:
foreach (Control control in myTextBoxPanel.Controls)
{
if(control is TextBox)
control.TextChanged += new EventHandler(control_TextChanged);
}
Just create one handler and point all the buttons to it.
var ButtonHandler = (sender, args) => {
var clicked = (Button)sender;
if (clicked.Text == "whatever")
//do stuff
else
//do other stuff
};
button1.Click += ButtonHandler;
button2.Click += ButtonHandler;
Alternatively, if you are creating controls in code, you could use one of the techniques specified in this answer.
Instead of giving 100 TextBoxes in a for loop 100 incrementing values, I have to write:
for(int i = 0; i <100; i++)
{
TextBox t = new TextBox(){ Id = "txt_" + i, Value = "txt_" + i};
t.TextChanged += new System.EventHandler(this.textBox_Textchanged);
Page.Controls.Add(t);
}
//and for event on TextChanged
private void textBox_Textchanged(object sender, EventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null)
{
////
}
}
Another thing to note: if you really need to edit 100 strings on one form, you should probably think about whether 100 text boxes is really the best way to do it. Perhaps a ListView, DataGridView, or PropertyGrid would be better suited.
This applies almost any time you think you need a huge array of controls.
If you are working with Web Forms and not MVC, you can acces a collection of controls on the page as shown in Using the Controls Collection in an ASP.NET Web Page. Essentially the controls collection is a tree with the page hosting the first level of child controls and some items having children of their own. See How to: Locate the Web Forms Controls on a Page by Walking the Controls Collection for an example of how to follow the tree.
Also, see How to: Add Controls to an ASP.NET Web Page Programmatically.
You can use the same event handler for multiple items as long as the signature required is the same.
For Windows Forms this is nearly identical since they're based on similar architectural models, but you'll want Control.Controls Property and How to: Add Controls to Windows Forms.
Keeping it simple:
TextBox[] keybox = new TextBox[16]; //create an array
for (int i=0; i<16; i++)
{
keybox[i] = new TextBox(); //initialize (create storage for elements)
keybox[i].Tag = i; //Tag prop = index (not available at design time)
keybox[i].KeyDown += keybox_down; //define event handler for array
}
private void keybox_down(object sender, KeyEventArgs e)
{
int index = (int)((TextBox)sender).Tag //get index of element that fired event
...
}
So here is the story - I have 2 DataGridViews - one of them is used as a display, the other one is user for editing or adding new entries. I don't use bindings on the edit one. When I am creating new entry I am just extracting the cells' values and passing them to an object. When I am editing though comes the problem.
The edit consists of 2 parts - one is to select the entry to be edited and display it on the second DGV. This is done with SelectionChanged event and the code is bellow. Then when editing is done it should just publish the new task the same way as creation. The thing is that when I am doing the edit and I come to the moment when I have to select from one of my cells - a ComboBoxCell - and I make a selection everything freezes. I cannot click anything else than this ComboBox until I press Esc - which obviously reverts the choice.
Why is this freeze happening and what causes it only when the data is cloned from the first DGV, but is okay when creating a brand new row? I am using VS2012 by the way and this is a windows forms application
Here is the code for duplication of the selected task - this method is the only thing in the DGV1's SelectionChanged Event handler:
public void createTemplateTaskToBeEditted(Form1 form1, ApplicationControl appControl)
{
form1.dg_templateView.Rows.Clear();
for (int i = 0; i < form1.dg_taskView.SelectedRows.Count; i++)
{
if (form1.dg_taskView.SelectedRows[i].Cells[0].Value == null)
{
form1.dg_taskView.SelectedRows[i].Cells[0].Value = false;
}
int index = form1.dg_templateView.Rows.Add();
form1.dg_templateView.Rows[index].Cells[0].Value =
form1.dg_taskView.SelectedRows[i].Cells[0].Value.ToString();
form1.dg_templateView.Rows[index].Cells[1].Value =
form1.dg_taskView.SelectedRows[i].Cells[2].Value.ToString();
form1.dg_templateView.Rows[index].Cells[2].Value =
form1.dg_taskView.SelectedRows[i].Cells[3].Value.ToString();
form1.dg_templateView.Rows[index].Cells[3].ValueType = typeof(ComboBox);
form1.dg_templateView.Rows[index].Cells[3].Value =
form1.PopulateAssignToComboBox(appControl.GetAllowedMembers(form1));
form1.dg_templateView.Rows[index].Cells[4].Value =
form1.dg_taskView.SelectedRows[i].Cells[5].Value.ToString();
form1.dg_templateView.Rows[index].Cells[5].Value =
form1.dg_taskView.SelectedRows[i].Cells[6].Value.ToString();
form1.dg_templateView.Rows[index].Cells[6].Value =
form1.dg_taskView.SelectedRows[i].Cells[7].Value.ToString();
form1.dg_templateView.Rows[index].Cells[7].Value =
form1.dg_taskView.SelectedRows[i].Cells[8].Value.ToString();
form1.dg_templateView.Rows[index].Cells[8].Value =
form1.dg_taskView.SelectedRows[i].Cells[9].Value.ToString();
form1.dg_templateView.Rows[index].Cells[9].Value =
form1.dg_taskView.SelectedRows[i].Cells[10].Value.ToString();
form1.dg_templateView.Rows[index].Cells[10].Value =
form1.dg_taskView.SelectedRows[i].Cells[11].Value.ToString();
form1.dg_templateView.Rows[index].Cells[11].Value =
form1.dg_taskView.SelectedRows[i].Cells[12].Value.ToString();
}
}
I've got a problem with adding some controls into a Panel(which gets "PopUpped" by a ModalPopupExtender) and add a CheckedChanged-EventHandler.
First of all, when user clicks on a button, this happens inside the CreatePanelChoose() function:
foreach (ListItem item in lbSupplier.Items)
{
string cbid = "cb" + i;
CheckBox cb = new CheckBox();
cb.ID = cbid;
cb.Text = item.Text;
cb.AutoPostBack = true;
AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender mecbe = new AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender();
mecbe.ID = "mecbe" + cbid;
mecbe.TargetControlID = cbid;
mecbe.Key = "SupplierKEY";
mecbe.BehaviorID = mecbe.ID + i;
//Also adding a Label
phModalPopupExtender.Controls.Add(new LiteralControl("</br>")); //phModalPopupExtender is a PlaceHolder
phModalPopupExtender.Controls.Add(cb);
phModalPopupExtender.Controls.Add(mecbe);
phModalPopupExtender.Controls.Add(lbl);
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = cbid;
trigger.EventName = "CheckedChanged";
UpdatePanelMatrix.Triggers.Add(trigger);
i++;
ButtonOK.Enabled = false;
}
lblText.Text = "Select one Supplier";
ModalPopupExtender1.Show();
Then i add the EventHandler in the Page_LoadComplete:
As you can see it also gets asigned to the control (I think).
The ModalPopup shows up correctly, but if I click one of the CheckBox, then it just closes it without going into cb_CheckedChanged, but it makes a Async postback ...
If I check Request.Form["__ASYNCPOST"] its true and Request.Form["__EVENTTARGET"] is also correct. (It gives me the unique id!)
Request.Form["__EVENTARGUMENT"] is empty.
I think I also need to say that I use a masterpage.
The problem shouldn't be the lifecycle of the page, because msdn says:
LoadComplete
Raised at the end of the event-handling stage.
Use this event for tasks that require that all other controls on the page be loaded.
Its the onliest place it makes me think it would be right.
Btw: yes i looked trough the topics here allready, but nothing helped me ... (google fo sure also)
Edit 1:
if (IsPostBack)
{
if (recreating == true)
{
CreatePanelChoose();
}
}
In CreatePanelChoose i do the foreach now everytime when its a postback! But it still doesnt fire cb_ChangedChecked ...
Edit 2:
MSDN-Page-Lifecycle also says:
PreInit
Raised after the start stage is complete and before the initialization
stage begins.
Use this event for the following:
Create or re-create dynamic controls.
So i tried to recreate the Panel there. But i dont have the ListItems there to get the values ... ?!
Okay, gave up ...
If someone would still have an answer, it would be great!
Right now I dont use the OnCheckedChanged-Event of the CheckBoxes anymore.
I just let them select a CheckBox and on the OnClick of the ButtonOk I loop through the CheckBoxes and check which one is selected.
I created a few radiobuttonlist controls on my project, they're created every time the page is loaded, i want to get the value of the radiobutton that the user has selected, but since my radiobuttons were created dynamically, i don't know how to acces to their values nor how to create their event handlers. Is there a way to assign a name or id to the control when i create it?
i hope you can help me.
I create a seires of radiobuttlist on the page_load event, with the text and their values been pulled out of a database. now, the user has to choose one of the options from that radiobuttlist and i want to get the value of the radiobutton the user checked. how do i do that if i don't know the name nor the id of the radiobuttlist since they're created dynamically.
this is what i've got:
for (int i = 3; i < numfields; i++) {
if (dr[i].ToString() != "" && dr[i] != null){
r.Items.Add(new ListItem(dr[i].ToString(), dr[i].ToString()));
//r.SelectedIndexChanged += new EventHandler(rowSelectedIndex);
}
}
so basically i use my datareader to loop through the data in the database, if the value from the field isn't empty or null, then i add an item to the radiobuttlist called "r"
i tried to create an eventhandler for that too, but since i have never worked with them i really don't know what to do. :(
I'm so sorry if i seem way too pathetic.
Taking a quick look at your code:
for (int i = 3; i < numfields; i++) {
if (dr[i].ToString() != "" && dr[i] != null){
r.Items.Add(new ListItem(dr[i].ToString(), dr[i].ToString()));
//r.SelectedIndexChanged += new EventHandler(rowSelectedIndex);
}
}
The most obvious thing that jumps out is your if statement. You should first check for null:
if (dr[i] != null && dr[i].ToString() != ""){
As if dr[i] is null, you'll get an exception (as you'll be trying to call the ToString() method on a null object.
If the contents of dr are always going to be strings, you might consider writing:
if(!String.IsNullOrEmpty(dr[i]){
I also note you start your indexing at 3 - is this because you want to skip the first 3 fields?
Wherever you create your variable, 'r', you can set the name and ID properties. You can use the ID property to look for the control on PostBack. So if you created your radiolist like so:
RadioButtonList r = new RadioButtonList();
r.Id = "MyRadioButtonList";
r.SelectedIndexChanged += MyRadioButton_SelectedIndexChanged;
Which would point at the following event handler:
private void MyRadioButton_SelectedIndexChanged(Object sender, EventArgs e) {
... Do Stuff ...
}
There are several ways of finding your control when you post back; you can look in the Request.Forms collection for a control matching the name of the control you submitted, or, more appropriately, you can use the FindControl method with the ID you gave the control. See C#, FindControl for a post with a method (by Jeff Atwood!) that will search the entire hierarchy of controls for your control.
When you add a dynamic control is important, too. If you add it too late in the page lifecycle then it will not be available on PostBack. See http://support.microsoft.com/kb/317515 for more details on just when to add a control. There are plenty of resources for Dynamic ASP.Net controls around too.
You could put your RadioButton into a list as you create them. This is also when you want to add your handlers.
RadioButton rb;
for (int i = 1; i < 5; i++)
{
rb = new RadioButton();
rb.AutoSize = true;
rb.Location = new System.Drawing.Point(25, (i*25) + 25);
rb.Name = "radioButton" + i.ToString();
rb.Text = "radioButton" + i.ToString();
//Add some event handler?
this.Controls.Add(rb);
lstRadioButton.Add(rb);
}
Whenever you want to know which one is selected you can do a foreach loop of your list and look if your RadioButton is checked.
foreach (RadioButton rButton in lstRadioButton)
{
if (rButton.Checked == true)
{
//Do something
}
}
You are maybe searching for TagName property if the programmatic name isn't enough for you.
The problem is that you are creating the controls in page_load. In order for their values to be posted back into the controls correctly, you must move this creation into the page_init method and recreate them every time.
Then, in page_load, you can access the values in the controls correctly. If you give them IDs using a consistent naming convention, you will be able to find them using the FindControl method or, in page_init, you can store them in a collection at the page or user control level.
I want to create buttons or list of items on the basis of number of items in my database or from list of items in my array and for each item create a onclick function for either buttons or any list of items
How about:
int y = 10;
foreach (string name in names)
{
Button button = new Button();
button.Text = name;
button.Position = new Point(10, y);
y += 20;
button.Click += HandleButtonClick;
Controls.Add(button);
}
You might also store the buttons in an array or a list... there's nothing particularly special about GUI controls that stops you from creating them at execution time just like any other object.
If that doesn't help, please give more information about what you need to do that the above doesn't help you with.
I have done it also by looking at Visual Studio code.