I am currently developing an application in which I want to display a UserControl inside a context menu. I was able to (somewhat achieve this using ToolStripControlHost). Shown in (NumericUpDownToolStripItem code): below is code for the object (written in VC++.net 2.0). Note: There are semi-similar SO questions on this, but none seem to be dealing with serializing usercontrols, just standard object in the usercontrols.
Shown following the object is the code for the actual usercontrol, which is a usercontrol with a label, and a numericupdown control.
The problem: When I load the designer for my application, I can add my NumericUpDownToolStripItem just fine, however, when I open up the use the exposed propertly to edit my usercontrol, None of that data is serialized into the InitializeComponent method of my NumericUpDownToolStripItem object. The effect of this is my control loads with all defaults at runtime. And every time I reload my form, the modifications are lost.
I have tried using the TypeConverter tutorial located On Msdn, but it didn't work properly. Everything compiled just fine, except my object became completely greyed out in the design grid (just the accessor property, not the entire menupic). Another problem I noticed is that this method isn't particularly designed for UserControls, which may have several different modifiable properties, and can't possibly have an overload for each.
So, I have the following questions:
- Is what I'm doing practical, or is my structure way-off the norms. I'm sure there are a lot of redundancy in the attributes.
- What is the correct method to serialize a usercontrol 'child' contained in another UserControl\toolstriphost 'parent'. Any properties in 'child' are simple values (Strings, Decimals, etc).
- When the TypeConverter class Isn't implemented, every time I changed a property (a labels text for instance), the painting of the object would get all jacked up and behave strangely, until I releaded the context\menu or form. Is there a proper way to inform the designer to repaint because I've made a change? (I used invalidate which has been dodgy at best).
Thanks in advance. I'm going to continue to research this and keep the question updated.
NumericUpDownToolStripItem Class:
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability::All)]
public ref class NumericUpDownToolStripItem : public ToolStripControlHost
{
public:
[DesignerSerializationVisibility(DesignerSerializationVisibility::Content |
DesignerSerializationVisibility::Visible)]
property LabeledNumericUpDown ^LabeledNumericUpDownControl
{
LabeledNumericUpDown ^get() { return (LabeledNumericUpDown^)this->Control; }
}
public: NumericUpDownToolStripItem(void) :
ToolStripControlHost(gcnew LabeledNumericUpDown()) {}
protected: void OnSubscribeControlEvents(Control ^control) new { //irrelevant to question }
protected: void OnUnsubscribeControlEvents(Control ^control) new { //irrelevant to question }
};
public ref class LabeledNumericUpDown : public UserControl
{
public: [ DesignerSerializationVisibility(DesignerSerializationVisibility::Content |
DesignerSerializationVisibility::Visible)]
property String ^DisplayText {
String ^get() {
return this->label->Text;
}
void set(String ^val) {
if(this->label->Text != val)
{
this->label->Text = val;
this->Invalidate();
}
}
}
//constructor
//destructor
//initiailecomponent
};