I'm having a strange issue that maybe being caused by my ignorance.
I have a treeview with an .AfterSelect and any time that i change the design of my form (in the deign view) the code gets removed for some reason.
here is my code
this.lstTreeView.AfterSelect += LstTreeView_AfterSelect; < this is the code that gets removed
this.lstTreeView.Location = new System.Drawing.Point(194, 56);
this.lstTreeView.Name = "lstTreeView";
this.lstTreeView.Size = new System.Drawing.Size(220, 498);
this.lstTreeView.TabIndex = 6;
this is the code that it allows to work.
private void LstTreeView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
TreeNode CurrentNode = e.Node;
string fullpath = CurrentNode.FullPath;
MessageBox.Show(fullpath);
NrDirSearch(fullpath);
}
if anyone can give me some advice on why the .AfterSelect is being removed that would be really helpful.
I suggest you:
in the windows form designer, click the tree view to select it
in the properties grid click the lightning bolt and scroll to find the AfterSelect event
right click the name AfterSelect and choose reset
hit save all
Close out of the soution entirely/shut down visual studio
restart/reload the solution
Go back to the AfterSelect event as above, the box for which should be empty
click the drop down and choose your existing event handler
save all, quit and restart vs and check that the setting stayed
If you're finding it didn't stick, check that you don't have your designer open in another program e.g. A text editor that keeps autosaving an old version of the file that lacks the event handler?
Incidentally, the above process is how you add event in Design view - click the relevant control, lightning bolt, scroll to event wanted, double click the name of the event and you will be transported to your own code behind with a new named eventhandler created and ready to be filled
If you don't write any code in it, and go back to the designer and Reset the event as per the bulleted list instructions then your event handler method in your code will disappear. If you write code into the event handler then it is not removed when doing a reset, only empty handler methods are removed during reset
Side note: be careful with Undo if you see a message saying something like "performing this undo will cause a loss of work elsewhere" it usually indicates that the windows form design or designer.cs code will change as a result of actioning the undo
Designer files are safe to edit manually and it's sometimes necessary if the contents have gotten into a state where they are crashing the designer. I most often encounter this when deleting event handler s from my code that are still referenced in the designer. A screen appears saying a problem is preventing the forms designer from appearing, indicating the error line in the designer file. I have additionally in the past edited the designer directly to set large numbers of properties without the faff of using the designer - be mindful not to have a windows forms designer open at the same time as editing the designer.ca file because the forms designer will probably overwrite your changes. So long as you keep in mind that opening the same file in any two different editors at the same time can lead to conflict and loss of work, and take steps to ensure that edits in one editor are reflected in another before proceeding with further edits in the other editor, you'll be fine :)
Edit: having said that paragraph above, Mickey D made me realise an important point I'd overlooked:
The designer.cs file is read by the forms designer and uses to build the contents of the form, buttons, properties etc. As such if you are going to edit the designer.cs in a text editor you should limit your edits to only those things the forms designer can make use of, understand, represent and preserve when it next writes the file. Adding a line to set a button to enabled is fine. Removing a line that is causing it to crash is also good. Putting 27 methods that implement your entire program's database access strategy in is not a good idea as it will not be heeded or used to build the form when the designer reads the file and hence lost when the designer writes the file. If you're unsure of the difference between what will and won't be preserved stick to removing or fixing existing lines only rather than adding new lines of code
You should never[1] modify *.designer.cs files. They are code generated. Any changes you make are subject to being overwritten.
Instead either use the WinForms GUI Forms Designer to visually setup event handlers or you can do so in code in your form’s code-behind .cs file.
There are plenty of resources on the Net on how to use the WinForms designer.
[1] see Caius Jard's comment below for an exception to the rule that I concur with
Related
I've hit a frustrating issue with a software project I'm working on. I've got help set up on various forms such that if I press F1, the application's CHM file is opened.
I want it to always open to the topic related to the current form, however it currently opens to a different location depending on what part of the form is in focus. If some fields are in focus, it opens to the top of the first page of the help document; and if other fields are in focus it will open, correctly, to the page and heading related to the current form.
I have the following designer code for the various forms, and I'm only setting HelpKeyword on the form itself, not any of the form's controls.
this.helpProvider.HelpNamespace = #"Path\To\ChmFile.chm";
this.helpProvider.SetHelpKeyword(this, "TopicName.htm#heading_name");
this.helpProvider.SetHelpNavigator(this, System.Windows.Forms.HelpNavigator.Topic);
From experimentation, I've determined that items with either SetShowHelp(false) or Enabled = false are the only ones that show the correct chm help location. This applies when pressing F1 with them in focus (if they can hold focus), or pressing on them with the "what's this" help cursor.
As an example:
If focus is on the main dialog's first control (a TextBox which has a HelpString, which implicitly sets ShowHelp) and I press F1, I'll get sent to the overall application help page (undesired behaviour).
If focus is on a main dialog TextBox which does not have an associated help string, and I press F1, I'm shown the Dialogs help page, at the heading for the main dialog (desired behaviour).
The only workaround I've found for this so far is to set both HelpTopic and HelpNavigator on every control with a HelpString, but this is very heavy-handed and difficult to maintain.
Clarification
I am intentionally using both the "What's this?" help and the F1 help on the same forms. I will not accept a solution that says to disable "what's this" help for all controls on my form in order to allow the F1 help to work. It is a requirement for this application that interactive controls have a help tooltip, and that each dialog has a help section in the help document.
If there is no way to get these two help features to work together nicely, I will accept an effective workaround that does not sacrifice maintainability as my above workaround does.
It was only after your clarification that I was able to fully understand your question and reproduce the problem. This behavior was not known to me before.
Same undesired behaviour using Visual Studio 2019 on Windows 10 PC - it does not matter if it is coded in the Form_Load event or with the help of the IDE (Integrated Development Environment) in the designer code.
After some hours of experimenting (with the reproduced problem) I hopefully narrowed it down without fully knowing the real reason.
I have done the following steps and thoughts - FYI - experimentally (see special notes in the list below):
The default value of the HelpNavigator enumeration is AssociateIndex. If you accidentally set SetShowHelp = True and a required property is missing, the call to the Index tab may fail, corrupt something and goes to the CHM's home page topic. If you don't have an index tab in your CHM, another problem arises.
I deleted or renamed the file hh.dat several tines to reset all (!) CHM windows on my system to their default settings. Windows will create a new version of hh.dat when you next open any .chm file. You'd find hh.dat at C:\Users\%username%\AppData\Roaming\Microsoft\HTML Help. BUT - - no success with the existing problem in the first test phase.
For some more test only (code is not required later) I have tried if the Form3_HelpRequested is triggered. BUT - that did not work in the first test phase.
private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
// do whatever you're gonna do here
DialogResult dr = MessageBox.Show("HelpRequested on Form1 was fired!\n\nOpen CHM help?","Test case", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
// FALSE will also open any associated help file
hlpevent.Handled = false;
break;
case DialogResult.No:
// TRUE will prevent windows from also opening any associated help file
hlpevent.Handled = true;
break;
}
Last as a hard step I deleted the HelpProvider component, have inserted this again and set all properties correctly a second time. NOW - it is working for me. Controls with the property ShowHelp=True now show the assigned topic and controls with the property ShowHelp=False now show the help topic of the form as expected.
You know - this can be a complex step and should be done in a test environment first. Make sure that all properties are set correctly and that the topic is accessible in the CHM via HelpKeyword.
// Tell the HelpProvider what controls to provide help for, and what the help string is.
this.helpProvider1.SetShowHelp(this.cityTextBox, true);
this.helpProvider1.SetHelpNavigator(this.cityTextBox, HelpNavigator.Topic); // make sure to set "Topic"
this.helpProvider1.SetHelpKeyword(this.cityTextBox, #"/Garden/flowers.htm");
this.helpProvider1.SetHelpString(this.cityTextBox, "Enter the city here.");
After giving the city textbox focus and F1 the help viewer window is shown. Using the "What's this" ? button in a second step is resulting in:
tl;dr
The definition of the properties via designer code or program code is more a decision based on personal preferences. I myself prefer to set values in the program code rather than via the controls properties window of Visual Studio.
If you add here all the properties of the controls for the help functionality as code, you can easily comment out for fixing problems. In a form with many controls, it is easier to save parts of the code externally and insert them again later. But as I said - everybody likes it different.
// set F1 help topic for first form
private void Form1_Load(object sender, EventArgs e)
{
helpProvider1.SetHelpNavigator(this, HelpNavigator.Topic);
helpProvider1.SetHelpKeyword(this, #"/HTMLHelp_Examples/Jump_to_anchor.htm#SecondAnchor");
}
BTW - the "What's this?" help for large programs means a high effort and in my experience it is used less and less in help authoring (CHM's). This kind of help has a long history from the times of Visual Basic 6, for example. Today you often find only one help topic for a form or a dialog in which the single controls are explained. The problem you describe then does not appear at all.
FYI - in earlier days a ALIAS and MAP files was required and maybe used today by TopicId. The purpose of the two files is to ease the coordination between developer and help author. The mapping file links an ID to the map number - typically this can be easily created by the developer and passed to the help author. Then the help author creates an alias file linking the IDs to the topic names.
Creating Context-Sensitive Help for Applications
Where to specify topic id in c# windows application
So I have a TreeView in C# and I'm loading icons for folders via P/Invoke. It's working, but on icons which are custom (so to speak), they change to some weird icon, as seen in the image below:
On "Regular" folders, i.e. ones without custom icons, this doesn't happen. Also on things like my HDD icons, it doesn't happen. This is the code I'm using to set the icon key
ImageKey = node.FileInfo.UniqueIcon;
SelectedImageKey = ImageKey;
As you can see, there's no way SelectedImageKey is different from ImageKey. However, the icon is still being set as the 0th index of the ImageList.I have confirmed via the debugger that the keys are staying the same, after the object is added.
So any ideas why this would be happening only for some icons?
Thanks.
Update
I found a workaround, but I'm not calling it a solution. If I add this to my code:
private void FolderTree_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
e.Node.SelectedImageKey = e.Node.ImageKey;
}
I'm not calling it a solution, because that command only has to run once for it to work. I know that because if I put it on the AfterExpand event, then after it does it for one bad one, all the others work after that, even before they're expanded. So it's like something just isn't clicking until after, and resetting just one makes all others work.
Using VS2013 Pro, WinForms, the debugger keeps deleting my event handlers. (I place them inside the Form.Designer.cs file)
I've only started noticing it recently and I'm positive I haven't changed any settings.
Can anyone else replicate this or is it just something on my system?
Steps to replicate:
Create new project C# WinForms
Add a split container > Inside panel two of the Base container, nest another split container.
In the Form.Designer.Cs file, hook up a Click event handler to the nested panel 1 container.
Run. -Click container - should work fine.
Exit Debugger > Change color property of the nest panel 1.
Run > Can no longer click?
Inspect Code > Event Handler has been deleted?
If you added your event handler manually then anytime you change something from the Designer the Form.Designer.cs is regenerated and will delete your event handlers (the ones added manually in the code)
What you need to do is to add the event handler from the Control properties.
For example if you code this in the Designer:
myControl.Click += myClickHandler;
it will be deleted anytime you change something in the designer, because the whole .Designer.cs file is regenerated and for some reason the VS is not aware of the event handlers added manually.
You;ll see that if you add the event handler from the Control properties window (in the designer) the generated code will look like this:
myControl.Click += new EventHandler(myClickHandler);
Another workaround is to add the handler outside the .Designer.cs class, but the easy way is to add the handler from Designer :).
This is a simple scenario:
I add an event to a control on the form by double clicking on its field (in Events part). But, then I decide that it was unnecessary and delete the automatically generated method. I'll run the program and it gives an error telling me that the event still exists in the InitializeComponent() and I must delete it from there.
So, is there anyway to avoid deleting the event "manually"? Is there anyway to fully delete it without leaving any trace (specially in InitializeComponent())?
Update: Also, another question arose:
When I delete the method from the code, the method name in the event field will disappear. So, if the InitializeComponent() is linked to these events, why isn't it updated with the empty event field?
You should use again the events grid and right click on the event you have inserted.
Select the Reset Menu option. This will remove the event handler assigned in the InitializeComponent and the code of the emtpy event in the code designer.
Note, that if you add code at the event, Visual Studio doesn't remove the new code.
The best way to do this is through the Properties grid in the Designer. You can click the Reset button or just delete the text and it will remove the event hook-up in the InitializeComponent() method. If your method is empty in your code behind, it will also delete it there:
It makes sense that you would have to manually delete the method body if it contains code in case it accidentally got Reset in the designer or if your method is referenced from some other part of your code. Visual Studio is gong to err on the side of caution.
If you delete the method body first, the reason it is not deleting the references to it probably in part has to do with cutting-and-pasting code. If you wanted to move the method to a different place in your code, the acting of cutting it would sever the references to it. After you pasted it, then you would wonder why your event was no longer be called. Again, error on the side of caution since it's not that difficult for the developer to track down extraneous code.
This pertains to C# 2017. So hopefully it would help others.
I'm new to C# (or at least back to code it) and ran with the same issue.
I commented out the event that I did by mistake. Then in the Error list, you will find an error there because that event is missing. Double click on it. It'll take you to the Designer code that "wires" the event. Once there, find the unwanted event and comment it out/delete it. Take care!
Look at the properties window when you select the Control. Click on the little flash and you'll see the Events listed, along with your event (Click or whatever), and your event will have the name of the assigned method behind it. Just delete that method.
That deletes the method, only if it's empty and otherwise unused though, which is quite reasonable. After all you might have put a lot of work into that event handler. (note: Just tried it again and apparently it doesn't always delete empty methods even though it did a few minutes ago. weird.)
In the designer you go to the events tab for the control in question, select the event that has the unwanted handler; and delete the name of the handler. Then save the form again.
This doesn't delete the method itself I think, (possibly unless it's empty or just been added).
Update
I dare say the reason for why it nearly always doesn't delete the method is because it could be used as a handler on another control's event. After all, in the UI you only asked to remove one event's handler; not every handler bound to that method. Then there's the question of whether the back-end code is dirty (i.e. unsaved) - checking whether the method is empty or not isn't reliable in that case. Yes, all of these could be worked around, but having to delete the method manually isn't exactly a hardship :) and at least this way VS doesn't end up deleting methods you actually want to keep.
Go back to the form and hit CTRL+Z.
I created a user control using C# for windows form application. This user control has some properties. In runtime, if the user does not enter values for this properties I want to show a message box and exit the application.
The problem is when I write the checking code in the Load event of User Control. When I drag & drop it on the form the message box will appear.
private void UserControl1_Load(Object sender, EventArgs e)
{
if (_getFirstPageArgument==null || _getFirstPageArgument.Length==0)
{
throw new Exception("Some Message");
}
}
How do I distinguish between load on the form and load on run time?
I fear there is a larger problem here. But to solve your immediate problem (if I understand correctly...) There is a form attribute called DesignMode. When you are in the visual studio design mode, this will be true. At runtime, this will be false.
For beginners, #Nimas case can be a good study point to understand that Visual Studio actually runs and executes parts of our code even when we are in design time, which is why the constructor is invoked. Even "DesignMode" property is not 100% reliable. You can find an interesting note here related to that http://weblogs.asp.net/fmarguerie/archive/2005/03/23/395658.aspx
If you only want to know when the type itself has been loaded into the runtime (not a specific instance), you can put code into the static constructor for that class.
If I'm misinterpreting your question, please clarify using a timeline when you want specific events to happen.