|
|
|
The General Winforms Interview Questions consists the most
frequently asked questions in Winforms. This list of 100+ questions guage your
familiarity with the Winforms platform. The q&a have been collected
over a period of time from various blogs, forums and other
similar Winforms sites
|
43. Design Time Serialization
|
| 43.1 How to make
my Component add itself to the contained Form's IContainer list?
|
| 43.2 How do I
prevent the default values of my Localized properties form being set?
|
| 43.3 How do I
force the changes in base class fields to be serialized via a base class
property in the inherited type's designer?
|
43.1 How to make my Component add itself to the contained Form's IContainer
list?
|
|
You do this inorder to ensure that your component gets disposed along with the
contained Form (logical parent).
All Form derived classes come with an IContainer field into which many of the
.Net components like ImageList and Timer add themselves to. The Form will
dispose the contents of this IContainer from within its Dispose. Scenario 1
In order for your Component to get added to this IContainer list, all you have
to do is provide a constructor that takes IContainer as the one and only
argument. The design-time will discover this constructor automatically and use
it to initialize your component. You should then add yourself to the IContainer
in the constructor implementation.
Note that for this to work your Component should not have a custom
TypeConverter that can convert your type to an InstanceDescriptor.
|
public class MyComponent : Component
{
public MyComponent()
{
}
public MyComponent(IContainer container)
{
container.Add(this);
}
}
|
Scenario 2
Your components might have more constructors besides the default constructor
and you might have a custom TypeConverter that provides an InstanceDescriptor
to let your designer use a non-default constructor for initializing your
component in code.
In this case, the above approach will not work because you do not have an
IContainer-argument only constructor.
You now have to recreate what the design-time did for you. You have to provide
a custom IDesignerSerializationProvider to do so. The attached
ContainerInsertingSerializationProvider class can be used to get the above
effect.
|
43.2 How do I prevent the default values of my Localized properties form being
set?
|
It is normal to have Properties in your Control/Component whose default values
are inherited from some other Control/Component.
In such cases you will normally prevent the designer from storing the
property's value in code (using either DefaultValue attribute or the
ShouldSerializeXXX pattern). However, if that property is Localizable and
Localization is turned on, then the property's value will be forced to be
stored in the resource. This will break your property-inheritance logic.
For example:
|
|
[
Localizable(true)
...
]
public Font MyControlButtonFont
{
get
{
if(this.buttonFont == null)
return this.Font;
else
return this.buttonFont;
}
set
{
this.buttonFont = value;
}
}
private bool ShouldSerializeMyControlButtonFont()
{
if(this.MyControlButtonFont == this.Font)
return false;
else
return true;
}
|
42.3 How do I force the changes in base class fields to be serialized via a
base class property in the inherited type's designer?
|
|
Sometimes you might want to let the designer serializer serialize the changes
in base fields via a property rather than the field itself using the
AccesssedThroughProperty attribute as follows:
|
|
public class MyBaseForm : Form
{
[AccessedThroughProperty("MyList")]
private ArrayList myList;
public ArrayList MyList
{
return this.myList;
}
}
|
|
Then when the above form is inherited and items get added to the inherited
form's designer, code will be added as follows in the inherited form's
InitializeComponent:
|
private void InitializeComponent()
{
... ... ... ...
this.MyList.Add(aNewItem);
... ... ... ...
}
|
|