.Net C# Design View errors - c#

I have subclassed a Treeview and on instantiation it loads a new ImageList (and the associated Images).
Whenever I switch to the designer view, it's also trying to run this code, however the images aren't in the designer's path, so it crashes. I ended up putting in a hack to see if the current directory is "Visual Studio", then do nothing... but that's so ugly.
I find this happening for other things. If a control is trying to use objects during load/initalization that are only available while the program is running, then the Design View cannot bring up the control.
But is there a way to get around this?
I guess what I'm hoping for is having a try/catch for the Designer (only) with the ability to ignore a few errors I know will be happening (like FileNotFoundException, etc.).
Thanks

Everything that inherits from System.Windows.Forms.Control has a DesignMode property that returns a boolean indicating if you are in design mode or not. You could use this to determine when to/when not to load external resources.

Usually it is better to move the loading of these resources to an override of OnLoad as they are rarely required directly at construction. This fixes the issue you are seeing and means that only trees which get displayed at least once will perform these additional resource loading steps.
Otherwise, you can just exclude these steps during design time by checking the DesignMode property and acting accordingly.

This is a fine pattern to use if you're making a control library with a sample of images when shown in the designer or hook ins to other designer features but as a pattern for development I'm not sure it's very effective.
I would suggest shifting your "business logic" (in this case your loading of certain images into a treeview) outside of the bounds of your treeview control. In your case I would place the logic within the Load event of the form that the control is inside:
public void Load(object sender, EventArgs e)
{
string path = "c:\somePath\toAwesome\Images";
myFunkyTreeView.AddImages(path);
}
For larger apps I personally think you want to shift the logic even out of the forms themselves, but this is debatable measure as it requires additional plumbing as a trade-off for the flexibility this provides.

Thanks for pointing me in the right directioon guys.
I had tried registering to the OnLoad event, but that event is triggered when the Design View comes up, so that didn't quite work for me (am I doing something wrong?).
Anyway, I looked a bit more into the DesignMode property. It can only work for Controls, and sometimes your object may not even be a control.
So here's the answer I prefer:
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) {
// design-time stuff
} else {
// run-time stuff
}
Found it here.

Related

VisualStateManager.GoToState() ignores useTransitions

I have a UserControl that has visual states in it. When the control constructs, I want to move to one of the states which is the "initial" one (not Default - there are modifications).
public MyUserControl()
{
this.InitializeComponent();
Loaded += MyUserControl_Loaded;
VisualStateManager.GoToState(this, "HideImageState", false);
}
However, when the control loads up, there's an obvious transition happening (the one that HideImageState represents).
Why is that if I am passing in useTransitions?
Since you aren't providing any more information, there are few things to work through "generally" that might help. Again, I am shooting from the hip with common problems...
The first is that your storyboard is inaccurate. If you created your transitions in Blend, then this is not likely. But if you coded them by hand, then the targets may not be what you expect.
The animations could also be occurring but being occluded by other elements in the UI. This can sometimes occur when you are resizing an object inside a container that cannot stretch.
Finally, and most importantly, if your visual state transitions are in a user control that is wrapped in a Viewbox then your view states are ignored for some reason.
There are other possible reasons for you to get the result you are seeing. However, with so little information given, I can't keep on guessing. I would assume one of the above three reasons.
Best of luck!

VS 2008 designer and usercontrol

I have created a custom data grid control. I dragged it on windows form and set its properties like column and all & ran the project. It built successfully and I am able to view the grid control on the form.
Now if i try to view that form in designer, I am getting following error..
Object reference not set to an instance of an object.
Instances of this error (1)
1. Hide Call Stack
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.GetMemberTargetObject(XmlElementData xmlElementData, String& member)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.CreateAssignStatement(XmlElementData xmlElement)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.XmlElementData.get_CodeDomElement()
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.EndElement(String prefix, String name, String urn)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.Parse(XmlReader reader)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.XML.CodeDomXmlProcessor.ParseXml(String xmlStream, CodeStatementCollection statementCollection, String fileName, String methodName)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomParser.OnMethodPopulateStatements(Object sender, EventArgs e)
at System.CodeDom.CodeMemberMethod.get_Statements()
at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, CodeTypeDeclaration declaration)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload)
If I ignore the exception, form appears blank with no sign of grid control on it. However I can see the code for the grid in the designer file.
Any pointer on this would be a great help.
I have customized grid for my custom requirements like I have added custom text box n all. I have defined 3 constructors
public GridControl()
public GridControl(IContainer container)
protected GridControl(SerializationInfo info, StreamingContext context)
I have this problem all the time...it sucks.
[Ramble(on)]
Here is what I think I know:
When designing place the control on a form. Build and refresh often..this will let you know what change caused the designer to barf.
Close visual studio all the way an re-open....I cannot tell you how many times I have chased a designer error that was the designer being "stuck".
It is very important that you understand : The designer is really, really stupid...like bag of rocks stupid.
Any public fields or properties of custom object types will almost always cause designer confusion*. I find the following attributes will clear up most of these problems:
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
Public fields or properties without a default constructor will always cause designer confusion. When you drop a user control on a form the designer effectively creates the control..so any public object needs a clear creation path. I have found that the easiest way around this (read hack) is keeping the non-trivial custom classes private and expose public properties as a facade.
-- Did I say restart visual studio because sometimes the designer is "stuck" on an error that doesn't exist ?..I hope I did.
[Ramble(off)]
I hope some of this helps..
*designer confusion: Instead of showing your controls the designer shows you a useless error message that might or might not include the dire warning that it is protecting you from code loss...blah, blah.
It sounds like a NullReferenceException is thrown in your control's default constructor (the one without parameters). Obviously, this exception is only thrown at design time since you say it works at runtime. Do you perform any initialization code in this constructor, like data base calls or similar? Or do you use any instances which might not be available at design time?
It looks like the form-designer is trying to initialize the control. Yet, the property it is trying to initialize may have been removed from the UserControl. There are lots of way to troubleshoot this problem. I recommend you debug the control in design-time. It is the surest way to find the problem. Check out "MSDN Search" for "design-time control debugging" at http://social.msdn.microsoft.com/Search/en-US?query=design-time+control+debugging&ac=8
I had run in to the same error check whether your Windows Form class inherits from System.Windows.Forms.Form class as in Form1:Form Hope dis helps !!!!

Interactive Design-Time User Control

I apologise if the title was confusing, it took me nearly 5 minutes to finally think of a title for this one...
Okay, you know how in Visual Studio Express when you add a TabControl to the Form, and you can click on the right-arrow on the top right of the TabControl and it will add a new TabPage, or remove one?
Well, I'm creating a User Control where I need people to be able to switch between Panels (my user control is made up of several Panels). I know this is possible as I've used a Ribbon Control in the past and you could add new buttons etc in the Designer View.
Can somebody please provide any suggestions/advice on how I might go about acheiving this?
Thank you
If I understand your question correctly, you're talking about smart tags.
The process is a little bit involved, so I'm not going to try to post a complete sample. Instead, I'll refer you to this tutorial on the subject. To make a long story short, you have to create a custom designer, and register one or more custom actions. You can use this to create a combo box listing the available panels and switch between them when the selected item is changed.
(Note - the term "smart tags" has two distinct meanings in Visual Studio - I'm specifically talking about the visual designer smart tags, not smart tags in the code editor).
When you make a control that is inherited from Control, you have to make use of a couple of properties such as IsDesignMode, you can then construct event handlers especially for within Design Mode:
if (IsDesignMode){
// Handle the interactivity in Design mode, such as changing a property on the
// Properties toolbox
}
Suppose the control has an event such as MouseClick, you can do this:
private void control_MouseClick(object sender, MouseEventArgs e){
if (IsDesignMode){
// Do something here depending on the Click event within the Designer
}else{
// This is at run-time...
}
}
Another I can think of is 'ShouldSerialize' followed by a publicly accessible property in order to persist the property to the designer-generated code, suppose for example a Control has a boolean property Foo
public bool Foo{
get{ return this._foo; }
set{ if (this._foo != value){
this._foo = value;
}
}
}
public bool ShouldSerializeFoo(){
return true; // The property will be persisted in the designer-generated code
// Check in Form.Designer.cs...
}
If ShouldSerializeFoo returned false, no property is persisted, its the opposite when true, it will be buried within the Form.Designer.cs code...
Hope this helps,
Best regards,
Tom.

C# Lock WinForm Controls

In a program I have written users can add controls to the form and move them around and set some properties in a pseudo design mode. I want to be able to lock all these controls into one location when they press a button to switch to "data mode". How can I do this? I wanted to do be able to loop through all the controls and use the Lock Property but I noticed it didn't show up in intellisense.
Thanks!
The Locked property is not a real property -- it is one which is added in by the Windows Forms designer (like the Generate Member and Modifiers "properties"). You would therefore need to simulate it yourself, either at the form level or (if required) at the control level (say with a dictionary of which controls are locked), and manually check it in the code you've written for moving controls around.
I am assuming by "pseudo-design mode" you do mean that your application is in a run-time state, and the end-user is experiencing a "virtual design mode" : please correct me if I am wrong.
But, I am assuming you are referring to the design-time 'Locked property of controls, and that you wish to "emulate" this at run-time ... correct ?
I'm also assuming you are attaching mouse up/down/move handlers to the controls you do allow to move around, probably by looping through all, or a subset of, the controls on the form (or a collection you are maintaining of controls allowed to be moved).
If my assumptions are correct, I would go for removing the event handlers that enable moving when you need to disable control movement, then restoring those event handlers when you need to allow controls to be moved again.
One main reason being that it is, imho, "best practice" to control event-handling rigorously (leaving event handlers "in-place" can interfere with object disposal ... although that may, in no way, apply to your scenario here).
One more idea : you have an "invisible" Panel docked 'fill to the Form : on this panel are all controls that can be moved : this may allow you to more easily "narrow your focus" on which controls you "spend" this extra code on. The drawbacks in using this approach are usually :
if you use hostingForm.ActiveControl to determine which control got the mousedown (and, thus, can then be moved) : you'll find some controls, like labels, and pictureboxes, do not become the activecontrol of the form when clicked, but most do.
you have a "z-order" thing to think about since a control not in your panel encapsulating the controls you wish to allow to move sent behind the pseudo-transparent panel will be hidden.
For these reasons, imho, I think disabling and re-enabling event handler attachments is best, most simple, and since it can be done when the controls are "down-cast" to their control "identity" :
private void enableControlsMove()
{
foreach (Control theControl in panel1.Controls)
{
Console.WriteLine(theControl.Name);
theControl.MouseDown += new MouseEventHandler(theControl_MouseDown);
theControl.MouseUp += new MouseEventHandler(theControl_MouseUp);
theControl.MouseMove += new MouseEventHandler(theControl_MouseMove);
}
}
private void disableControlsMove()
{
foreach (Control theControl in panel1.Controls)
{
Console.WriteLine(theControl.Name);
theControl.MouseDown -= theControl_MouseDown;
theControl.MouseUp -= theControl_MouseUp;
theControl.MouseMove -= theControl_MouseMove;
}
}
I use it this way.
best, Bill
Locking controls prevents them from
being dragged to a new size or
location on the design surface.
However, you can still change the size
or location of controls by means of
the Properties window or in code.
MSDN
I guess it's a visible-to-designer-only property. I think you'd have to implement your own freeze mechanism - a little flag to toggle between Design and Use modes.
Update: It seems that custom designer classes can add properties to controls based on whether they are in Design Mode or not.
More details available here if you intend to take the VS architectural hammer path. In any case, worth 10 mins of reading time.
Custom Design-time Control Features in Visual Studio .NET - Dino Esposito

Error Creating Control - Custom Control

I have a custom control and it works fine...except that the control cannot be rendered on Design Time. ( I am using VS 2008)
I am thinking many people who develop custom controls encounter this problem...The error I get is "Error Creating Control - CustomControlName" Object reference not set to an instance of an object.
I want a work around. or at least debug this...(Since this is a design time issue how to debug?)
I have tried if( !DesignMode) code on OnInit, OnPreRender, RenderContents, CreateChildControls Methods ( I am just shooting in the dark)...
Help pls. I really hope this is not a VS bug!
BFree's comment is the most likely issue, for a control to display in the design view it needs a parameterless constructor as the design viewer doesn't know how you would normally instantiate the control.
If you do have a parameterless constructor, can you paste some code in to show what's happening?
As Glenn mentioned the first issue could be no parameterless constructor.
The second could be you are calling methods during the OnLoad or other methods you mentioned that have parameters that are not initialized or some sort of attempt at database calls etc that is normally done at run-time.
Unless they fixed this bug recently* and I'm not aware, something to keep in mind is the DesignMode property works for the first and second level of nested controls but beyond that it normally doesn't work right. (Such as form containing a UserControl[1] that holds another UserControl[2], the DesignMode works on the form and [1] but not [2]).
Also to agree with Glenn, seeing some of the code will help.
*From my very recent experience working with nested usercontrols it hasn't been fixed.
In your OnPreRender & CreateChildControls methods it's making a call to this.Page. You might want to try wrapping them in a
if (this.Page != null)
{
.....
}
Because I don't think you'll have a Page object at that point & I'm pretty sure PreRender & CreateChildControls will be called in design view. I haven't written custom server controls for a while though, so I could be wrong (been working in MVC lately).
Glenn, the error ur getting a VS bug and no fix has been released yet.

Categories