Discussion:
Composite Control Issue
(too old to reply)
Patricio Vidal
2008-04-02 00:03:27 UTC
Permalink
Hello,

I have a composite user control that contains a ListView and a PictureBox
inside a SplitContainer When I drag this user control to another user
control I would like the user to be able to edit the ListView control. How
do I do that? I created a public property in the composite control to
expose the ListView object and added the Browsable attribute, but that
doesn't allow me to click on the ListView and edit it.

This functionality is available in the SplitContainer control because when I
click on one of the Panels it shows the property <SplitControlName>.Panel1
(or 2) and you can edit it, so that I assume it should be possible to do it
on my control.

Thank you in advance for your help.

Regards,
Patricio.
Linda Liu[MSFT]
2008-04-02 05:03:33 UTC
Permalink
Hi Patricio,

To enable your composite user control to support the same design-time
function as the SplitContainer, you need to author a custom designer for
the composite user control to extend the design-time environment.

In detail, you extend the appearance of your custom design UI by
implementing a Glyph class and extend the behavior by implementing a
Behavior class. The Bahavior class is subordinate to the Glyph class. You
attach a Behavior object to a Glyph object in your Glyph type's constructor.

You override the GetHitTest method in the Glyph class to return a Cursor
object when the mouse pointer is over your glyph's hot spot. When the
design environment receives a value from your GetHitTest method that is not
null, it activates the Behavior object associated with your Glyph.

You override Behavior class methods like OnMouseDown to paint the selection
rectangle around the nested ListView control and set the primary selection
to this ListView control.

For more information on how to extend the appearance and behavior of
controls in design mode, please refer to the following MSDN document:
http://msdn2.microsoft.com/en-us/library/ms171820.aspx

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-03 09:02:17 UTC
Permalink
Hi Patricio,

Thank you for your prompt reply and sample project!
when I created the DerivedListView class it had no designer support,
A derived control inherits the designer from its base control, if any. So
the derived ListView control still has the same designer support in Visual
Studio as the ListView control does.

In your sample project, open the ListViewWithPictureBox in the designer and
select the DerivedListView control on it, you should see a smart tag
appears on its top right corner and clicking on the smart tag opens a smart
tag panel, which means the DerivedListView has the same designer as the
ListView control.
My idea was to look for the Control that gets "hit" by the click, select
it, and then make it active to active its designer somehow. I could not
find a click method to override.

.NET 1.x way to extend the design time behavior is to override methods in
the ControlDesigner class, e.g. the OnMouseDragBegin, OnMouseEnter and etc.
In this model, much of the UI designer logic is implemented in the
EventHandler. Because there are several designated areas on a control that
a user may manipulate, this model required that you write a great deal of
supporting logic.

In addition, the ControlDesigner class doesn't provide a mouse click method
to override.

.NET 2.0 introduce BehaviorService which provide a more flexible solution
to extend design time behavior.

In your practice, you could create a Glyph and a Behavior class. When the
mouse enters into the bound of the DerivedListView, return a hand cursor in
the override GetHitTest method within the Glyph class so as to activate the
associated Behavior object. When the user clicks the mouse, select the
DerivedListView as the primary selection and invalidate the adorner to get
the Glyph to paint a red dot rectange around the DerivedListView.

I have modified your sample code to include the above changes and will send
it to your hotmail mailbox.

Open the project on your machine and build it. Open Form1 in the designer,
and move the mouse over the DerivedListView within the
ListViewWithPictureBox control, you should see the mouse becomes a hand
cursor. Click the mouse, you should see a red rectangle appears around the
DerivedListView and the Properties window shows the properties of the
DerivedListView.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Patricio Vidal
2008-04-04 07:29:16 UTC
Permalink
Hello Linda,

One thing that is happening is that when I change a property of any
contained control, the Property editor turns white. I can re-select the
contained control type from the pull-down list and continue working, but it
is inconvenient. Could it be related to the property name issue?

Thank you,
Patricio.
Thank you Linda. I updated the sample you sent me to make it more generic
and now it has all the functionality I wanted!.
The only thing missing is that the Property Editor doesn't know the name
of
the property that is editing, it only shows the type. When you click on
the
Panel1 in a SplitContainer the Property Editor shows
"spliContainer1.Panel1
System.Windows.Forms.SplitterPanel", but in my case the names are empty
and
only the type is shown. On the other hand, the Designer generated code
knows about the property because it is generating the appropiate code, but
//
// listViewWithPictureBox1
//
//
//
//
this.listViewWithPictureBox1.DerivedListView.BackColor =
System.Drawing.SystemColors.ControlLight;
this.listViewWithPictureBox1.DerivedListView.BorderStyle =
System.Windows.Forms.BorderStyle.None;
...
How do I give the name of the property to the Property Editor? I am
attaching the updated sample. The CompositeControlDesigner is now
abstract
and there is a ListViewWithPictureBoxDesigner that provides the list of
composite controls.
Thank you again,
Patricio.
Post by Linda Liu[MSFT]
Hi Patricio,
Thank you for your prompt reply and sample project!
when I created the DerivedListView class it had no designer support,
A derived control inherits the designer from its base control, if any. So
the derived ListView control still has the same designer support in Visual
Studio as the ListView control does.
In your sample project, open the ListViewWithPictureBox in the designer and
select the DerivedListView control on it, you should see a smart tag
appears on its top right corner and clicking on the smart tag opens a smart
tag panel, which means the DerivedListView has the same designer as the
ListView control.
My idea was to look for the Control that gets "hit" by the click, select
it, and then make it active to active its designer somehow. I could not
find a click method to override.
NET 1.x way to extend the design time behavior is to override methods in
the ControlDesigner class, e.g. the OnMouseDragBegin, OnMouseEnter and etc.
In this model, much of the UI designer logic is implemented in the
EventHandler. Because there are several designated areas on a control that
a user may manipulate, this model required that you write a great deal of
supporting logic.
In addition, the ControlDesigner class doesn't provide a mouse click method
to override.
NET 2.0 introduce BehaviorService which provide a more flexible solution
to extend design time behavior.
In your practice, you could create a Glyph and a Behavior class. When the
mouse enters into the bound of the DerivedListView, return a hand cursor in
the override GetHitTest method within the Glyph class so as to activate the
associated Behavior object. When the user clicks the mouse, select the
DerivedListView as the primary selection and invalidate the adorner to get
the Glyph to paint a red dot rectange around the DerivedListView.
I have modified your sample code to include the above changes and will send
it to your hotmail mailbox.
Open the project on your machine and build it. Open Form1 in the designer,
and move the mouse over the DerivedListView within the
ListViewWithPictureBox control, you should see the mouse becomes a hand
cursor. Click the mouse, you should see a red rectangle appears around the
DerivedListView and the Properties window shows the properties of the
DerivedListView.
Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-07 08:30:19 UTC
Permalink
Hi Patricio,

Thank you for your reply!

I do notice the new problem. I have consulted in our internal discussion
group about this and got an answer.
We need to call the ControlDesigner.EnableDesignMode method to enable
design time functionality for a child control.

In your latest modified sample project, add a method override for the
Initialize method in the ListViewWithPictureBoxDesigner class as follows
should solve the problem:

public class ListViewWithPictureBoxDesigner :
CompositeControlDesigner<ListViewWithPictureBox>
{
public override void Initialize(System.ComponentModel.IComponent
component)
{
base.Initialize(component);
ListViewWithPictureBox relatedControl = component as
ListViewWithPictureBox;
EnableDesignMode(relatedControl.PictureBox, "PictureBox");
EnableDesignMode(relatedControl.ListView, "ListView");
EnableDesignMode(relatedControl.DerivedListView, "DerivedListView");
}
}

In fact, after using the ControlDesigner.EnableDesignMode method, we
needn't implement a Glyph and a Behavior to select the nested control
visually and set it as the primary selection in the designer at all because
the EnableDesignMode method has made all these happen.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Patricio
2008-04-07 14:26:41 UTC
Permalink
Hello Linda, that is great! It works very good.

Anyway, the Glyph and Behavior implementation were an interesting insight to
the process. I appreciate EnableDesignMode() much more now :-).

Thank you again and best regards,
Patricio.
Post by Linda Liu[MSFT]
Hi Patricio,
Thank you for your reply!
I do notice the new problem. I have consulted in our internal discussion
group about this and got an answer.
We need to call the ControlDesigner.EnableDesignMode method to enable
design time functionality for a child control.
In your latest modified sample project, add a method override for the
Initialize method in the ListViewWithPictureBoxDesigner class as follows
CompositeControlDesigner<ListViewWithPictureBox>
{
public override void Initialize(System.ComponentModel.IComponent
component)
{
base.Initialize(component);
ListViewWithPictureBox relatedControl = component as
ListViewWithPictureBox;
EnableDesignMode(relatedControl.PictureBox, "PictureBox");
EnableDesignMode(relatedControl.ListView, "ListView");
EnableDesignMode(relatedControl.DerivedListView,
"DerivedListView");
}
}
In fact, after using the ControlDesigner.EnableDesignMode method, we
needn't implement a Glyph and a Behavior to select the nested control
visually and set it as the primary selection in the designer at all because
the EnableDesignMode method has made all these happen.
Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
Continue reading on narkive:
Loading...