This must be a FAQ, but I can’t find a duplicate question!
There are lot of different attributes that control what the WinForm Designer does with properties on a custom control, I am never clear on the one I should use in this case.
I am looking for:
Designer does not show property in grid
Designer does not read value of property
Designer does not set property to default value
E.g. Designer behaves as if the property was not there.
Designer does not complain if it has already done one of the above before the attributes were added (hard!)
Background.
The code that is giving me the problem is:
this.eventListControl.FilterSets =
((SystList<FilterSet>)(resources.GetObject("eventListControl.FilterSets")));
The FilterSets property should never have been touched by the winforms designer; it is now not Serializable and MsDev falls over every time a form that used the eventListControl is changed!
I think you can use [Browsable (false)] and [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
The second attribute prevents the property from appearing in InitializeComponent
Related
In great need help with the strange binding problem with regards to Winform UserControls.
Its like this.
Have a form with a UserControl
UserControl has a System.Windows.Forms.BindingSource control
BindingSource has a DataSource set to an entity POCO type at design time.
UserControl has controls that are bound to properties on the POCO class. An example: CreateDate
No problem in designer of the UserControl itself.
But entering the designer og the Form containing the UserControl, I get a designer error window with the message: "Cannot bind to the property or column CreateDate on the DataSource. Parameter name: dataMember"
In runtime I get the same error, but first when Show is called on the form. Here I can see on the stack trace that it is thrown after a CheckBinding call.
The error occurs no matter if the DataSource on the bindingSource is set or not during the creation (in constructor) or Load event on the form.
I can see that the designer sets my data source like this in the designer file: this.bindingSourceRecipe.DataSource = typeof(Data.Entities.Recipe);
I have tried so many things to solve this problem. It seems very strange as this is a dead simple form/control setup and should be a trivial use of Winforms usercontrols.
If I set the bindingSourceRecipe.DataSource at runtime to a temp. instance just after the InitializeComponent() in the form then no error occure;
InitializeComponent();
ucRecipeBaseControl.Recipe = new Recipe() { Id = 0, CreateDate = DateTime.Now, Name = "" };
So it seems that the Initialization cycle of the form/control somehow clears the binding source knowledge about its DataSource type.
This does of course not happen if a place all the user controls and BindingSource Directly on the form. Then everythings works, and it does not matter if the DataSource ever gets set to an instance of a Data entity.
Seems like a complete mystery to me, should be dead simple, and I'm kind of lost on what to do.
Any help or suggestions are highly appreciated.
BR Peter Meldgaard
Ahhh, got it nailed at last. It was caused by a mix of Winform designer behavior and my code. I was setting the binding controls datasource in a public property setter, so I could save a copy of the entity, to be able to compare the changed and the org. The thing is that when you put a control with a public property on a form, then the designer initializes this property to null inside the designer generated code. I did not know that. So everytime the usercontrol was instantiated, the DataSource got set to null, clearing the typeof(dataentity), albeit loosing the binding information.
Adding a null check in the setter, and only update datasource when value is not null fixed the issue.
With relation to my previous question mentioned here:
Custom DataGridViewColumn value disappears after loosing focus
I tried to change my EditControl class. I added an override to the 'OnTextChanged' method. When I run and debug my application, I came to know that the 'EditingControlDataGridView' property for the custom control is not being set. Even though in the designer code I am adding the column into the MetroGrid.
What can the issue be?
When I add a control to a form through the designer, not all properties of the control appear in the designer code. For example, when I add a ListBox the UseWaitCursor property does not appear in the designer code unless it is set to True. When I change it to False it disappears from the designer code, which makes me think that the properties somehow have defaults and don't appear in the designer code if left at default.
Can someone please help me understand how the designer works and where all this is tracked. The reason I ask is I am currently writing a class that extends a third party ActiveX control which I plan to initialize dynamically at run time. I was going through the designer code (when the third party control is added through the designer) and a lot of its properties do not appear there.
This is done with the [DefaultValue] attribute. The Control.UseWaitCursor property looks similar to this:
[DefaultValue(false)]
public bool UseWaitCursor
{
// etc..
}
So if you leave the value at False in the Properties window then the designer knows that it should not display the value in Bold and that it is not necessary to put the property assignment in the InitializeComponent() method since the default is already good. An ActiveX control will certainly have a lot of properties set at its default value as well.
I have a form that inherits from another from. In the designer, whenever I adjust something like control size or location, VS auto-generates a resx file for that form. The resx just contains some KeyValuePairs for comboboxes, w/c are unnecessary really since these values are already defined in the parent class.
Aside from this, the designer.cs also gets update w/ inherited properties such as Text, NumericUpDown.Value, DisplayMember, ValueMember, etc, w/c again are already defined in the parent class.
I know the designer.cs is supposed to be update w/ the new location and size, but I don't want it to update other stuff that's inherited from parent class.
Is there a way to prevent this, and just let the designer update the location and size?
UPDATE:
I found that the ComboBox.Items.AddRange() gets added to the Designer.cs and .resx file due to binding logic that I have in OnLoad(). This is primarily preventing the designer to load properly when the form is reloaded on the Designer.
I modified OnLoad to run the binding logic only when DesignMode is false.
The form no longer throws errors when reloading the designer, but some of the control properties are still unnecessarily added back to the Designer.cs whenever I change any property via the property dialog.
UPDATE2:
Totally prevented the designer from generating unnecessary control properties by applying suggestion here.
Now all that's generated are control location and size.
I am finding that Design View (DV) is nice, but trying to change the way it automagically injects code into InitializeComponent is very hard. And sometimes its automagical code breaks the program.
For example, DV automatically sees every single property of my custom UserControl, and then it assigns every single property to some value in InitializeComponent. But I don't want it to assign values to some of the properties because some of my setters will throw a runtime exception if not used correctly. I could correct InitializeComponent manually, but anytime I make a change to the design, SharpDevelop will just regenerate the function again.
And there's another case where I have the Default Constructor set the size based upon certain factors, but then InitializeComponent will immediately set it to another static value.
How can I tell DV to not automagically assign values to certain properties I define?
Unless I misunderstood your scenario, it seems like you're barking up the wrong tree by trying to modify or reconfigure SharpDevelop's behavior. Even if you manage to change it, you won't affect Visual Studio's behavior, and you won't help any of the other consumers of your custom control who don't happen to (and/or don't want to) configure their designer accordingly.
Instead, it seems that you should just mark the properties exposed by your custom control with the [DesignerSerializationVisibility] attribute. This indicates to the designer exactly how that property's value should be serialized into the InitializeComponent method.
You have a choice of three different values:
Visible indicates that the value for the property should be persisted in initialization code
Hidden indicates that the value for the property should not be persisted in initialization code
Content indicates that initialization code should be generated for each public (not hidden) property of the object assigned to the property
The default value is Visible, which causes a property's value to be serialized whenever possible.