
Customizing the MDI frame background
Multiple document interface (MDI) applications have a main form that contains other forms which, in turn, contain the documents being worked on. This popular application style is catered for very well in Windows Forms but has one minor drawback that raises one very frequently asked question. How do I custom-draw the MDI host form's background?. The secret to this puzzle lies in the structure of the MDI application. The main form, which one might imagine was the place where the MDI children are managed, is in fact only the parent of an MdiClient control. The reason that this is not well known is because Microsoft decided that this control was going to be one of the infamous classes for which the MSDN entries say "This type supports the .NET Framework infrastructure and is not intended to be used directly from your code." Thankfully the class is only enigmatic, not totally mysterious and so, assuming that it is based upon the Control class it's possible to add handlers to the various events of the control and get it to do some custom drawing for us in the Paint or PaintBackground cycles. A very common desire is to place a bitmap image on the form background. The problem is that when you select the form and add the background all you get is a form that flickers, displays the background momentarily and still shows the awful battleship grey surface that we all hate so much. To put a bitmap on the MdiClient you need to find it by searching through the controls in the form and then force the bitmap upon it like so: foreach(Control c in this.Controls) { if(c is MdiClient) { c.BackgroundImage=Image.FromStream(this.GetType().Assembly.GetManifestResourceStream("MDIbg.Bitmap1.bmp")); } }
Dim c As Control For Each c In Me.Controls If TypeOf c Is MdiClient Then c.BackgroundImage = Image.FromStream(Me.GetType().Assembly.GetManifestResourceStream("MDIbgVB.Bitmap1.bmp")) End If Next c
Figure 1. An MDI client with a bitmap background. Drawing a gradient on the MdiClient background can be done by handling the correct events just as you would with any other control. The following listing shows how to perform this task. Note how the SizeChanged and Paint events are used to update and repaint the surface. public Form1() { // // Required for Windows Form Designer support // InitializeComponent();
foreach(Control c in this.Controls) { if(c is MdiClient) { c.Paint+=new PaintEventHandler(PaintClientBG); c.SizeChanged+=new EventHandler(SizeClientBG); } }
Form f = new Form(); f.MdiParent=this; f.Show(); }
protected void SizeClientBG(object sender,EventArgs e) { ((MdiClient)sender).Invalidate(); }
protected void PaintClientBG(object sender, PaintEventArgs e) { MdiClient mc = (MdiClient)sender; e.Graphics.Clip=new Region(mc.ClientRectangle); LinearGradientBrush lgb = new LinearGradientBrush(mc.ClientRectangle,Color.LightBlue,Color.Navy,90f,false); e.Graphics.FillRectangle(lgb,mc.ClientRectangle); lgb.Dispose(); }
Public Sub New() ' ' Required for Windows Form Designer support ' InitializeComponent()
Dim c As Control For Each c In Me.Controls If TypeOf c Is MdiClient Then AddHandler c.Paint, AddressOf PaintClientBG AddHandler c.SizeChanged, AddressOf SizeClientBG End If Next c
Dim f As New Form() f.MdiParent = Me f.Show() End Sub 'New
Protected Sub SizeClientBG(sender As Object, e As EventArgs) CType(sender, MdiClient).Invalidate() End Sub 'SizeClientBG
Protected Sub PaintClientBG(sender As Object, e As PaintEventArgs) Dim mc As MdiClient = CType(sender, MdiClient) e.Graphics.Clip = New [Region](mc.ClientRectangle) Dim lgb As New LinearGradientBrush(mc.ClientRectangle, Color.LightBlue, Color.Navy, 90F, False) e.Graphics.FillRectangle(lgb, mc.ClientRectangle) lgb.Dispose() End Sub 'PaintClientBG
Figure 2. A gradient on an MDI Client background As you can see, once you know where to find the MdiClient control in the main form's list of controls you can do just about anything with it that you could with a normal control. Perhaps draw a clock on the background or use it for other user feedback. Return to Windows Forms Tips and Tricks Copyright Ramuseco Limited 2004. All rights reserved.
|