I have a userControl which starts a timer. It looks like the XAML designer is trying to call that code, which links to some back-end database stuff. I keep getting an unhanded exception error in the design screen.
Any ideas how I can stop the designer trying to run the code?
XAML designer will call the UserControl's constructor when loading in designer. In order to avoid this you can place a if condition as follows in your UserControl constructor
if(System.ComponentModel.DesignMode) return;
You can also check in this way
if (!System.ComponenyModel.DesignProperties.GetIsInDesignMode(this))
{ // write constructor code here }
Related
I've created a custom user control, that is essentially a custom button within my windows form app. I managed the redirect of the click event to using the following code:
Control[] customButtonControls = button.Controls.Find("buttonInUserControl", false);
Button nestedButton = (Button)customButtonControls[0];
nestedButton.Click += new System.EventHandler(this.button_click_handling_function);
I've appended this to the Window_Name.Designer.cs file below the generated code for the control with my button_click_handling_function being defined in my Window_Name.cs file.
The issue is that when I then click back to the Window_Name.cs[Design] page, I am met with an error page. I will include screen shots to better show the errors. Basically it is a super unhelpful page. It tells me that I have an index out of range error on my Array, but the stack call makes no sense.
If I try to build my Solution, I am met with NO compile errors and my program acts exactly as intended. The click event triggers the function just as before.
Thanks in Advance.
Portions of the designer code are run at design-time. The index out of range error is probably because at design-time there are no controls found yet by that Find call so the array is empty. You are not checking for 0 length so when you de-reference it you get the error.
It works at run-time because at that point the controls have been instantiated.
The secondary problem though is you should not put things into the Designer.cs files since that code is auto generated by the designer and could be regenerated at some point and your added code lost. Put that code in the Window_Name.cs after the InitializeComponent call.
Let's say that I have a custom control that inherits from another control.
I want to set some properties of this control, so I add something like this inside the constructor, for example:
public class MyControl : Canvas
{
public MyControl()
{
if (getSomeTestValueFromAppSettings())
{
this.Background = ColorConverter.MyStaticBrushProperty1;
}
else
{
this.Background = ColorConverter.MyStaticBrushProperty2;
}
}
}
Now, everything works fine inside the app, so no problems there.
The point is that if I add something like this inside my control constructor, I get an error with the XAML designer, and it tells me it can't create an instance of the control.
That's ok, since of course the constructor is trying to access the app local settings, and it can't do that inside the XAML Designer.
I'm currently using this as a workaround: I simply wrap all my conde inside the constructor inside a try/catch block, and if I got an exception (that only happens inside the XAML Designer) I simply ignore it.
This way the code stillworks fine on the phone, and it doesn't crash the XAMl Designer.
I don't think that this is a good solution though, a try/block inside a class constructor is not something I think could be considered a good programming practice.
I was hoping there was something like a "compiler directive" that tells the compiler when it's not actually running on a device/emulator, but just inside the XAML Designer, but I didn't find anything like that.
Do you have suggestions or other better ideas on how to solve that problem?
Thanks!
Sergio
There is actually a build-in method for situations like this.
Just use this code
if (DesignerProperties.GetIsInDesignMode(this))
{
// Design-mode specific functionality
}
So essentially, I have a custom user control called ExcelDisplay. I try to drag it over in visual studio from the toolbox into my webform in the same project and I get a missing method exception. At one time the constructor was parameterized, but I changed it after deciding it was a bad design idea.
It looks like it is saying the constructor is missing, but its obviously there.
My winform to house the control is empty with the exception of the autogenerated code visual studio puts there.
The code for my ExcelDisplay's constructor looks like this.
namespace STS_Console.UserControls
{
public partial class ExcelDisplay : UserControl
{
public ExcelDisplay()
{
InitializeComponent();
DataDisplay.Columns[0].HeaderText = "Data";
//debug
string x = DataDisplay.Columns[0].GetType().ToString();
x.ToString();
}
The error message is this.
So that error occurs when do I drag and drop in the designer like this
Anyway so that is my problem. I am not sure what is causing it or how to fix it. I would be glad to post additional code upon request.
You should put your user controls in a class library of their own. For the designer to work, it needs a compiled version of your user control. If you cannot compile your user control before you compile your form, you will get into all kinds of trouble.
Rebuild Solution fixed it for me, although if your making regular changes to your user control, you should put them into a separate project.
My particular problem, was a user control, within a user control.
I am creating an usercontrol contains a "Tao.Platform.Windows.SimpleOpenGlControl".
In my control's constructor, I have
{
InitializeComponent();
simpleOpenGlControl1.InitializeContexts();
}
My problem:
When I use the control on a "Windows Forms Application" it's ok, but if I put the computer at hibernate or sleep mode, when visual studio is open and form that contains the control, is in design mode, the next time I turn it on this error comes up:
Fatal Error
can not activate the gl rendering context
and visual studio is not responding!
What's wrong here? I am doing something wrong?
I am using Tao framework.
After implementing OpenGL chart solution, I encounter those error.
Every time I tried to close form, error occurred.
After few times of debugging, I found the reason.
The reason is like this.
On my form closing, Draw function tried to use OpenGlControl object ONE MORE TIME.
So I make condition to check the additional flag.
I solved my problem in this way:
In control's InitializeComponent(); I removed simpleOpenGlControl1 Initialization and then in control's Load() function, I have
isDesignMode = LicenseManager.UsageMode == LicenseUsageMode.Designtime;
if (!isDesignMode)
{
// init simpleOpenGlControl1
}
Now when my control is used in a project, there is no simpleOpenGlControl1 in design mode to make problem!
I'm working on an application so i have write an dll which contain a form with some additional work and methods. so in the beginning of my program the thread launch this form (from my dll) to get some informations and then hide it and initialize some components and the application form and then show it. when the thread come the line where it define new instance of the exported form
"MyForm inputform = new MyForm();"
it throw an Exception called "Top-level control cannot be added to a control." so i don't know what to do ?!!. i tried to take the code of the form from the dll source code and put it in the main program and it works.... .but still i want to know what happen and what impede my application from run that form from my dll.
thanks.
The line that raises the error is possibly not the line you show above, but likely one of the lines that follows it. I.e., if you have something like the following:
currentControl.Controls.Add(inputForm);
it will not work and raise the error you mention.
Instead, use inputForm.Show(ownerForm) to show the form when you want it and you should be fine. A form (a top level control) cannot be added to a normal control, like a panel, a textbox or a picturebox.
Note: if the line in your post does raise the error, then inside the form initialization code lies a piece of code that raises the error, check there