Prevent Designer from removing Attributes on Control members - c#

I want to mark certain controls on my Windows Form with Attributes. So I added the Attribute in my TestAttributes.Designer.cs:
[AmbientValue(true)]
private System.Windows.Forms.Label label1;
But whenever I change the Modifiers-property of label1 using the properties-window of the designer, the Designer silently removes my Attribute from the declaration:
public System.Windows.Forms.Label label1;
I tried putting the declaration in the TestAttributes.cs to not mess with the .Designer.cs file. But when changing the Modifiers property the declaration is moved back to TestAttributes.Designer.cs and the Attribute is gone.
How can I prevent the Designer from removing my Attributes?
EDIT:
The question should better be: Can I permanently move the declaration of a control out of the *.Designer.cs file, so I can apply an Attribute there? As I wrote above, it gets moved back in some cases.
Thank you!
richn

If you want to keep designer support, I recommend using an external class library.
namespace ClassLibrary1
{
[System.ComponentModel.AmbientValue(true)]
public class TestClass : System.Windows.Forms.Label
{
}
}
You can compile something like this to a class library, and then import it to visual studio. If you don't know how to do that, follow the instructions below.
Right click the toolbox
Click "Choose Items"
Wait. Do not make the mistake of terminating visual studio now.
Select Browse.
Select your dll file.

I normally don't like people who give the "don't do it" answer, but don't do it.
Changing the designer class is dangerous, and can almost always lead to unexpected consequences. The designer code is reserved for the compiler, and it should always look like the compiler expects it to look.
If you really wanted attributes in what would otherwise be your designer code, you should instead make an empty application, and do the forms code yourself. You shouldn't be trying to modify designer code anyway, if you don't understand how to do it from scratch
If that seems like a lot of work, you can always try to use the designer as a model, and then copy that over to a new, non-windows forms project.

Untill recently i was lead to believe that designer was just part of the code and it was not to be touched. I was wrong. Turns out you can rip the entire thing out and then compiler will throw an error at you. Okay, that's fine, just define your own stuff, completely thus eliminating the necessity for a designer. here is how. Say you have a tag
<div id="div1" runat="server">
and you want to make it invisible on the back side without any designer.cs file present (we deleted it). First reference it along with other declarations (i.e. outside of page_load, somewhere on the outside)
protected System.Web.UI.HtmlControls.HtmlGenericControl div1;
Remember however, you MUST reference EVERYTHING that you use on the front side that has a runat="server" tag. So say you have a page with only a runat="server" label, on the back we reference to it as
namespace yournamespace.something
{
public class yourpagetitle: System.Web.UI.Page
{
protected System.Web.UI.WebControls.Image imgLogo;
protected System.Web.UI.WebControls.TextBox tbDate;
protected System.Web.UI.WebControls.Label yourLabelName;
Notice I added image and a textbox as additional examples. And huzza! You have thus completely eliminated the need for designer.cs file. Oh, and do notice, designer.cs file is nothing more than what we just did above, but it does it for you automatically. ...most of the time... When it fails, time to handle things your own way. I'm sure if you reformat your computer, reinstall everything, etc etc etc things will work again, no doubt. This is just a legitimate work around for those who do not have time to babysit and troubleshoot every little hick-up Microsoft does.

Related

changing my windows form design removes some unrelated code

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

Visual Studio error when adding a library in the Form.Designer.cs

So basically I add this code to my Form1.Designer.cs:
this.comboBox1.Items.AddRange(Enumerable.Range(0, 30).Cast<object>().ToArray());
which requires adding using System.Linq; on top of namespace WindowsFormsApp. The program runs just fine, the only thing is that when I go back to the Form1.cs[Design] GUI part, Visual Studio returns me the following error: To prevent possible data loss before loading the designer, the following errors must be resolved.
I can ignore that and the program works just fine, but it kinda worry me. Is there maybe another way to add the using System.Linq; line without making VS get angry at you?
There is no reason to modify your designer generated code. Just put your line of code in your Forms constructor, after the line/region that is already there.
I suppose Visual Studio rewrites your file and removes the using. Try changing your code to
...System.Linq.Enumerable.Range(0, 30)...
That said. You shouldn't add code to the desinger file on any other place as in the default constructor (if present) after the call to InitializeComponent() or inside a protected virtual void Dispose(bool disposing) function (if present).
And even then you should move the constructor or dispose function to your form1.cs file.
If you want to add items to your combobox do this via the property grid and let visual studio take core about writing the designer file or do it in the appropriate event handler (I would suggest either load or shown event).
The InitializeComponent wouldn't be the right place for modifing controls, since the next time you open the form in the designer the items are added to the combobox and get serialized during save unless your write
public Form1()
{
InitializeComponent();
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
if(!designMode)
{
this.comboBox1.Items.AddRange(Enumerable.Range(0, 30).Cast<object>().ToArray());
}
}

how to copy paste a WPF Window (clone) and not have errors

I am using .Net 4.5.2 with WPF and C# 5.0. I created a Window in a WPF project. I would like to copy paste this window in the solution explorer, making a second window, and rename it to a new name.
When I do this, the new (copied) window's InitializeComponent() method always gives me an error. How does one cleanly copy a window (and it's code, etc.) in the solution explorer?
This question was answered partially here: Copy pasting WPF window gives error however the answer did not solve my issue.
My approach (that does not work):
Create a window and title it WindowTest
In the solution explorer, select WindowTest and copy, then paste it into the same project
Rename the new copied Window to WindowTestCopy
In WindowTestCopy, change the x:class property in xaml to be WindowTestCopy instead of WindowTest
Open the code behind in WindowTestCopy, and change any references to WindowTest to WindowTestCopy
Compile
Expected: no errors, the copy (clone) operation is successful
Actual: compile error "Cannot access non-static method 'InitializeComponent' in static context".
I have only this one error. Obviously InitializeComponent() is becoming an ambiguous reference, but it isn't clear to me how to make manual edits to the code to fix this. I wish that VS or Resharper would automatically assist me with this.
UPDATE
WindowTest contains two userControls that I had not mentioned previously. After the copy/paste occurs, for some reason the following xaml elements became malformed within WindowTestCopy:
xmlns:userControls....(ellided)
xmlns:userControls....(ellided)
By deleting these, Resharper determined that the userControl objects were missing xmlns reference tags and asked me if I wanted to import them automatically. I selected yes. After Resharper added the missing xmlns reference tags I was able to compile (all errors disappeared).
I do not have an explanation for why this happened. In my steps to reproduce, I do not edit the xaml and it should therefore be identical to the originating xaml. This is curious behavior, but at least there is a workaround as stated.
When it happened to me, it went like this:
Copy the xaml in solution explorer.
Rename the xaml in solution explorer.
Rename the x:Class in the xaml.
Rename the class name in the xaml.cs.
Rename the constructor in the xaml.cs.
Why is everything still broken? <== (you are here probably)
Realize there is secret voodoo witchcraft underneath.
Copy the contents of the xaml and the xaml.cs to a couple of notepads.
Delete the xaml from solution explorer.
Create a new xaml in the solution explorer with the name you wanted.
Overwrite both the xaml and the xaml.cs with the exact contents of the two notepads.
Errors are gone.
Someone else actually posted and then deleted had the correct idea, but brief on why.
The issue you were running into is due to a duplication of a class within the same project... even though in the solution explorer you can easily copy/paste a WPF form or any other class, user control class, etc. When copied, it suffixes the file names to " - Copy", and if you compile right away will fail. Reason being? In the class itself the class name and window name is the same. So, in the project you have TWO instances of the class and it is choking on that hoping for you to resolve the duplicates. I ran into this exact same thing early on in my WPF development.
So, now that I've explained WHY it is failing, here is what you would need to do, to correct the issue. I created a window in my sample project called "FirstWindowSample", so two files are created FirstWindowSample.xaml and FirstWindowSample.xaml.cs. The .cs version is the code-behind of the window (or user control class, the principle is EXACTLY the same.
If you look in the "FirstWindowSample.xaml" code (the visual-design version), the code will look something like...
<Window x:Class="YourProject.FirstWindowSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FirstWindowSample" Height="300" Width="300">
<Grid>
</Grid>
</Window>
Notice in the first line
x:Class="YourProject.FirstWindowSample"
You need to change the ".FirstWindowSample" to whatever you want for your new form such as
x:Class="YourProject.SecondWindowSample"
Next, change over to the CODE-BEHIND file "FirstWindowSample.xaml.cs".
namespace YourProject
{
/// <summary>
/// Interaction logic for FirstWindowSample.xaml
/// </summary>
public partial class FirstWindowSample : Window
{
public FirstWindowSample()
{
InitializeComponent();
}
}
}
This is the hard-reference of the class name and its corresponding constructor. Just change these to match the new window name you are expecting (such as sample SecondWindowSample)
namespace YourProject
{
/// <summary>
/// Interaction logic for SecondWindowSample.xaml
/// </summary>
public partial class SecondWindowSample : Window
{
public SecondWindowSample()
{
InitializeComponent();
}
}
}
At the end your project will now have a completely different class name that is not duplicated and cause compile errors. The FIRST time you run into this, yeah... a pain to find out. Once you get it, the next 2-3 times are the "oh-yeah" refresher... After that you sort of do it without thinking about it.
The issue was resolved by deleting all xlmns elements in the xaml and letting resharper automatically add them back in. I am not satisfied with this solution because it is not logical; however, it did resolve the compile error.

Square mouse pointer in Visual Studio 2008 designer

A strange issue with Visual Studio 2008. I have a winforms application that contains several forms.
On one of my forms, the mouse pointer has a square shape around the arrow, like in the attached image. I cannot get rid of it, no matter what I tried. The square keeps moving along with the mouse pointer. Seems funny, but it's really frustrating, really, because I cannot use the drag-and-drop functionality at all. This prevents me from working with the designer. Imagine that I cannot grab the edge of any control to resize it. I can move controls, though...
What is particular about this form is that it is derived from another form, like this:
public partial class MyForm : BaseForm
BaseForm is also derived from Form. I'd say nothing too uncommon.
Thanks for any idea.
Later Edit:
I found why I got an error when entering into MyForm's designer.
BaseForm has an Microsoft.Reporting.WinForms.ReportViewer component. The component was added as a private member.
When working with MyForm's designer, VS was automatically generating a new Microsoft.Reporting.WinForms.ReportViewer member for MyForm, so I got 2 members with the same name. One defined in the base class, one in the derived class.
I solved this by declaring the base class's member as public and regenerating the derived class, so no need to duplicate things.
Anyway, unfortunately, this did not solve my designer issue with the mouse cursor...
Chances are that the BaseForm has soe logic in its constructor or other eventhandlers that is supposed to run at runtime but not at DesignTime.
You could use:
if (!this.DesignMode)
{
// runtime only
}
to block out some logic at design mode
Have you tried,
Cursor = Cursors.Default;
or setting it to some other Cursors value?

Where is the Component Initialize Method in Asp.NET 3.5

I want to create my own naming convention for page events rather than AutoEventWireUp but I couldn't find Component Initialize methods any where ? Should I override it ? But in which class it is defined ?
Thanks...
Edit :
For example : I don't want to use Page_Load but LoadThisPage naming. So It should be like
Load += new LoadThisPage(sender,e);
I was expecting a InitializeComponent method where I can initialize page,controls etc. events handlers...But it turned out to be Constructor function :)
So what confused me is I thought there should have been a method like InitializeComponent which does things for me already created by Designer itself so I thought I could define my own event handler names within this method by overriding it in the say Default.aspx.cs .
But the answer was simple :) Thanks...
Your question isn't really clear as to what you're trying to do.
Page events are defined in the System.Web.UI.Page class, some of which are inherited from System.Web.UI.Control. You don't need to use AutoEventWireUp if you don't want to, and you're free to override all of the Page methods that would normally raise the lifecycle events (OnInit, OnLoad, OnPreRender, etc.) and then not call the base methods, effectively squelching the events from being raised.
You can see some limited discussion around this on this blog post.
As Hogan noted, this sounds like a bad idea. Could you expand on what you're trying to accomplish?
This sounds like a bad idea to me.
However, you should be able to find auto-created code by selecting the project display options, I believe it is right click in project explorer, and selecting display hidden files or display all files. Then you will see additional .vb files created by the system. You might also have click on the little plus sign.
additonal added notes
Most of the events (btw) are defined in the base class(es) in System.Web.UI.Page and not in the code created for a specific instance.

Categories

Resources