WinForms designer strips away event handler assignments when upgrading forms - c#

I am doing brownfield development, and have to deal with lots of old forms with code that looks like this.
//
// Button1
//
Button1.Location = new System.Drawing.Point(556, 447);
Button1.Name = "Button1";
Button1.Size = new System.Drawing.Size(136, 23);
Button1.TabIndex = 112;
Button1.Text = "Restart kontor";
Button1.Click += Button1_Click;
If I try to edit one of these forms, the form is upgraded. All the identifiers will then have the "this" qualifier prepended. Unfortunately Visual Studio 2015 will also simply strip away all event handler assignments in the file. That means the last line in the above example snippet will simply vanish.
Why does this happen? Is there a very simple way to prevent it?
I have found a workaround that is reasonably quick to work through for each form. The workaround is posted as an answer. It will cut my work upgrading these forms from days to hours.
If anybody knows of a quicker way, a proper fix perhaps, I'd like to know.

Workaround
Editing an entire form to fix broken event handler assignments can be very time consuming. This workaround speeds up the process significantly, by fixing the source before the designer tries to upgrade it. (I do not know if "upgrade" is the proper term, but who cares...)
Before allowing the designer to upgrade the form, edit the form source manually in this way.
Edit all lines with event handlers so that they explicitly do a new System.EventHandler. All you have to do to find the relevant lines is to search for "+=". This is what the line in the snippet from the question will look like then.
Button1.Click += new System.EventHandler(Button1_Click);
When this is done, you must somehow trigger the designer to upgrade the form. This can be done e.g. by changing the title of the form via the designer, and then change it back. The designer will now hopefully correctly upgrade all lines. The entire snippet in the question will then look like this after upgrade.
//
// Button1
//
this.Button1.Location = new System.Drawing.Point(556, 447);
this.Button1.Name = "Button1";
this.Button1.Size = new System.Drawing.Size(136, 23);
this.Button1.TabIndex = 112;
this.Button1.Text = "Restart kontor";
this.Button1.Click += new System.EventHandler(this.Button1_Click);
So far this way to handle the problem leaves me with upgraded forms that are easy to compare with the original forms, which is important when verifying the upgrades.

Related

cannot add or remove an event handler "method group" but the designer can

When I try to add or remove an event handler the error is "cannot assign … to a "method group". Yet the exact line of code in the designer compiles fine.
I am filling in list boxes so the user can select the items. There are several SelectedIndexChange fire backs that I do not want to fire until I have everything in place. I no no trouble coded a numeric up-down to prevent it firing but I cant get the listbox coded and am forced to use semaphores to prevent unwanted things from happening. I looked at the VS2017 build "xxx.Designer.cs" and copied and pasted the exact line of code into the "xx.cs" but that error shows up.
{
cb_AppNames_SelectedIndexChanged -= new System.EventHandler(this.cb_AppNames_SelectedIndexChanged);
FillAppBox();
cb_AppNames_SelectedIndexChanged += new System.EventHandler(this.cb_AppNames_SelectedIndexChanged);
here is the code from the Designer.cs
// cb_SelProj
//
this.cb_SelProj.FormattingEnabled = true;
this.cb_SelProj.Location = new System.Drawing.Point(86, 25);
this.cb_SelProj.Name = "cb_SelProj";
this.cb_SelProj.Size = new System.Drawing.Size(279, 21);
this.cb_SelProj.TabIndex = 0;
this.cb_SelProj.SelectedIndexChanged += new System.EventHandler(this.cb_SelProj_SelectedIndexChanged);```
fixme1.png shows error messaged and fixme2 shows code that has no err
![1](http://stateson.net/images/fixme1.png)
![2](http://stateson.net/images/fixme1.png)
An event (like SelectedIndexChanged) is like a list of callbacks, which are called when the event occours. If you don't want/need this event before you filled your listbox, then do not add the callback by designer, but in your code after filling the data.
In your example you don't use the same code as in designer. The desigener adds the method b_SelProj_SelectedIndexChanged. In your code you try to remove and add the event cb_AppNames_SelectedIndexChanged itself. This will not work. You can only add and remove a method to or from an event.
You are basically correct but the actual problem was (1) about 3 in morning looking at this, (2) was unable to get .png file to show up at this forum - still do not know what I did wrong, and (3) due to not being able to see the .png in the "big screen" so I did not notice I was using "_" instead of "." when I tried to code the following up
this.cb_AppNames.SelectedIndexChanged -= new System.EventHandler(this.cb_AppNames_SelectedIndexChanged);
I was using small font in VS2017 for code and did not see the problem though it is plain here:
this.cb_AppNames.SelectedIndexChanged -= new System.EventHandler(this.cb_AppNames_SelectedIndexChanged);
this.cb_AppNames_SelectedIndexChanged -= new System.EventHandler(this.cb_AppNames_SelectedIndexChanged);
Maybe it is not so plain. I cant even get the code paragraphs to show up in correct order. I thought I had problems at askubuntu when a moderator sarcastically edited my post but I finally figured it out there. Not sure what is wrong here and it is not 3 in the morning. FINALLY GOT THE CORRECT FORMAT!!! Not going to complain, thankful enough that this forum is available.

I can't see my design view on c#

I started working on a c# 2017 project, I closed the file of my program and the next time I opened it this error message showed up, if I try clicking on "omitir y continuar" the desing board is empty. I don't know what to do. If I click on the "iniciar" (start) button the program shows normally. And the line of code that says its wrong is:
this.button1.Click += new System.EventHandler(this.button1_Click);
Below is the image of the error.
This error indicates that you have a registered event for a button that does not exist - you must have deleted button1 from your form, but never removed its registered event.
You need to open your Form.Designer.cs file, where you will see the code line:
this.button1.Click += new System.EventHandler(this.button1_Click);
Remove this line and compile your project again, or switch to your Design view, which should now be fine.
Name of the reference variable (button1) is wrong or name of the method (button1_Click). Did you change any of them by your own? You have to chamge it in *.Designer.cs file accordingly.

Object does not match target type

I have a TableLayoutPanel with a grid of PictureBox controls within it. I'm trying to find a shortcut way to change them all to Label controls instead of manually deleting each one and placing new controls in each cell.
I thought I could go into the designer code and find/replace PictureBox with Label, but now I get an
"Object does not match target type"
error in Visual Studio's error list. I can't view the designer page now either. Is this not allowed? If it is allowed, what's the right way to do it?
If you take a closer look at the generated code:
label1:
this.label1 = new System.Windows.Forms.Label();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(134, 163);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(35, 13);
this.label1.TabIndex = 1;
this.label1.Text = "label1";
pictureBox1:
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(97, 75);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(100, 50);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
My guess is that the
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
is changed by you into something like:
((System.ComponentModel.ISupportInitialize)(this.label1)).BeginInit();
which doesn't work, and results in designer issues. Object does not match target type.
so, apply the changes you already did, remove the lines like:
((System.ComponentModel.ISupportInitialize)(this.label1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.label1)).EndInit();
and I think you're good to go.
Don't change designer code. That stuff is automatically generated. Not only can your changes cause unexpected behavior, but they can get over-written as well.
I would attempt to make a change or 2 to your form, or whatever your designer is behind, and hope it regenerates all it's code.
You can delete all the picture boxes in the designer, then add all the labels in the _load event (or another convenient event). That way it will be easier to change next time.
As Haxx illustrated, you will have to clean-up the extra initialization PictureBox requires as well. The error you received is a interface casting error. In your case, as Haxx guessed, the Label control doesn't implement the ISupportInitialize interface.
Unlike most, I am not afraid of changing designer code in the interest of expediency, for what you are doing, it is ok to do so. Just know your objects, check-in prior to doing so, and don't put custom code in there!

Learning .NET Development // Windows Forms in Visual C# - Linking Controls To Event Handlers

I am a Java programmer moving to .NET development and have about 5 years programmign experience. I usually write all my code in a text editor, omitting the IDE side of things. With Visual C# I am using the Visual Studio 2010 IDE. In order to get to grips with the interface I am following official Microsoft tutorials.
My question relates to creating event handlers for control items:
When designing, say, a windows form application, it is possible to drag controls directly onto the form (i.e. buttons, check boxes etc). The tutorial nstructs users to double click on a button control and double click on it to create the click event handler in the .cs file. This works absolutely fine and creates the following piece of code for a button with a (name) of showButton:
private void showButton_Click(object sender, EventArgs e)
{
}
Where is the link between the button and the event handler stored? As in, how does the compiler know which button the above event handler maps to?
Take a look at YourForm.Designer.cs at InitializeComponent() method.
You'll find the code similar to
//
// show
//
this.show.Location = new System.Drawing.Point(10, 10);
this.show.Name = "show";
this.show.Size = new System.Drawing.Size(75, 23);
this.show.TabIndex = 0;
this.show.Text = "button1";
this.show.UseVisualStyleBackColor = true;
this.show.Click += new System.EventHandler(this.ShowClick);

C# equivalent of Delphi's DisableControls/EnableControls

What is the C# equivalent of Delphi's DisableControls/EnableControls methods (used to disable updating of databound controls while iterating through the underlying dataset)? I have googled for half an hour and did not find an answer...
I have a list box and a rich edit box bound to a binding source, but I need to do an operation that iterates through the entire dataset, and both controls get updated as I move through the underlying dataset. In Delphi this is easy enough: enclose the block that does the iteration between DisableControls and EnableControls. I can't find the C#/.NET equivalent, and I have looked really hard!
IIRC, setting Enabled to false does not prevent the controls from reacting to data changes in WinForms.
Collection-bound controls like the ListBox typically have methods BeginUpdate() and EndUpdate() which temporarily disable visual updates.
Also, the property mentioned by DarkSquirrel might be worth a look
I don't have access to Visual Studio right now, so I can't test this, but look through the methods for the control instance. Code such as:
// set the Enabled property of
// the controls to False; this should
// disable the controls for user access
listBox.Enabled = False;
richEditBox.Enabled = False;
// perform iteration
// and other operations
// set the Enabled property back
// to True
listBox.Enabled = True;
richEditBox.Enabled = True;
The exact name of the property may differ slightly, but I'm pretty sure that this is what it is.
I assume you are using WinForms, in that case you can try using the methods SuspendLayout/ResumeLayout.
Code sample from MSDN:
private void AddButtons()
{
// Suspend the form layout and add two buttons.
this.SuspendLayout();
Button buttonOK = new Button();
buttonOK.Location = new Point(10, 10);
buttonOK.Size = new Size(75, 25);
buttonOK.Text = "OK";
Button buttonCancel = new Button();
buttonCancel.Location = new Point(90, 10);
buttonCancel.Size = new Size(75, 25);
buttonCancel.Text = "Cancel";
this.Controls.AddRange(new Control[]{buttonOK, buttonCancel});
this.ResumeLayout();
}
So far I know, you don't need to Disiable/EnableControls in C#, since this type of DataSet doesn't work with a current cursor, like Delphi TDataSets.

Categories