TLDR: I'm seeking the correct method for timing the rendering of a juxtaposed graphic for a particular control on a design surface so that the graphic always is painted ahead of the adornment glyphs when that control is selected.
This question concerns control designers for Winforms: When the user places a control on the design surface, I want to display a graphic above the client area of the control. I have succeeded to some extent doing that for a TableLayoutPanel (TLP) control by overriding its OnPaint event handler then using the e.Graphics object available to paint a peach-colored rectangle. Below is an image showing the results: a painted graphic that spans the width of the control and is 35 pixels high--remember, this is a designer instance of a control placed on a design surface (created with a BasicLoader):
However, within the designer, if I resize the control, the graphic always ends up below the resize glyph (the glyph that has the North/South and West/East arrows on it):
I've tried creating and maintaining various Boolean flags to suppress the OnPaint message under certain circumstances. For instance, I set a flag to indicate that the control was just resized (to see how I did that, see my recent question: BeginResize/EndResize Event for Control on WinForms Design Surface) in order to suppress the painting of the graphic, but that didn't work because an OnPaint event is inevitably raised after I've cleared a flag. I don't want saddle this question with details of all the flags and places I tried to use/set them but suffice it to say that I painstakingly spent hours experimenting--to no avail. I've concluded that there must be a better way.
How can I ensure that the glyphs remain on top when I paint my graphics?
Thank you!


I can think of a few solutions, including the followings:
TableLayoutPanelI think the first solution will suit you well, however the other solutions also some points.
I can also think of a solution based on
NativeWindowlike what has been implemented inErrorProvider, but It makes the post toooooo lengthy while the existing options are good enough. So I leave it to you if you like to pursue the idea.Solution 1 - Using Padding of the TableLayoutPanel
TableLayoutPanelhas aPaddingproperty and its layout engine respects to the padding well. You can use the padding area to render whatever you want:Solution 2 - Using Adorner and Glyph
For design-time rendering, I'll handle it using
AdornerandGlyph.If I was creating my custom designer, all the code belong to the control designer, but since you don't want to create a new control designer for
TableLayoutPanel, then the same way that I injected a new custom action in the action lists, here I'll getBehaviorServiceand I'll inject an adorner to the adorners of the control at design time and this will be the result:The behavior is quite similar to the other glyphs, it will be resized automatically when the control resizes and you don't need to do anything specific to handle the resize at design time.
Please note: It's a design-time solution and the painting is just being done at designer. In case you need a run-time solution, you need a totally different solution.
Here is the code:
Note:
To learn more about anchors, glyphs and behavior, take a look at the following links:
Solution 3 - Creating a custom panel, having header and editable content
You can create a custom panel having header and editable content. Then at design time disallow user from dropping content on the header part:
To do so, you need to create a new designer which enables the inner panel on design-time by calling
EnableDesignModemethod. Then for the inner panel, you need to create a designer which disables moving, resizing and removes some properties from designer.I've posted a detailed answer here: UserControl with header and content - Allow dropping controls in content panel and Prevent dropping controls in header at design time