///<summary></summary> public void CreateShadow() { if (Shadow != null) { Shadow.Dispose(); Shadow = null; } Height = ApptDrawing.LineH * 24 * ApptDrawing.RowsPerHr; Width = (int)(ApptDrawing.TimeWidth * 2 + ApptDrawing.ProvWidth * ApptDrawing.ProvCount + ApptDrawing.ColWidth * ApptDrawing.ColCount); if (Width < 2) { return; } Shadow = new Bitmap(Width, Height); if (ApptDrawing.RowsPerIncr == 0) { ApptDrawing.RowsPerIncr = 1; } if (ApptDrawing.SchedListPeriod == null) { return; //not sure if this is necessary } using (Graphics g = Graphics.FromImage(Shadow)) { ApptDrawing.ApptSheetWidth = Width; ApptDrawing.ApptSheetHeight = Height; ApptDrawing.DrawAllButAppts(g, true, new DateTime(2011, 1, 1, 0, 0, 0), new DateTime(2011, 1, 1, 0, 0, 0), ApptDrawing.VisOps.Count, 0, 8, false); } }
///<summary>Handles all double buffer drawing and rendering to screen. ///Creates one bitmap image for each appointment if visible, and draws those bitmaps onto the main appt background image.</summary> /// <param name="listAptNumsOnlyRedraw">Specify which appts to redraw. If null or empty then all appts will be redrawn.</param> /// <param name="drawSheetBackground">Recreates the background and everything other than the appointments. Typically only used by RedrawAll().</param> /// <param name="createApptShadows">Each individual child ContrApptSingle control will have it's own double buffer bitmap re-created.</param> /// <param name="drawToScreen">Draws the double buffer bitmap directly to screen once it has been modified. In rare cases the screen has already been updated so this wouldn't be necessary here.</param> /// <param name="isThreaded">Spreads the work of generating each appt shadow over multiple threads. Typically only used by RedrawAll().</param> /// <param name="drawCachedBitmapOnly">Skips all double buffer bitmap modifications and simply redraws existing to screen. Typically only used by OnPaint().</param> public void DoubleBufferDraw(List <long> listAptNumsOnlyRedraw = null, bool drawSheetBackground = false, bool createApptShadows = false, bool drawToScreen = false, bool isThreaded = false, bool drawCachedBitmapOnly = false) { if (_isRedrawingOnThread && !isThreaded) //We are already performing a RedrawAll on a thread so do not allow re-entrance at this time. { return; } if (!_isShadowValid) //if user resizes window to be very narrow { return; } Action drawShadowToScreen = new Action(() => { if (!_isShadowValid) { return; } using (Graphics g = this.CreateGraphics()) { g.DrawImage(_shadow, 0, 0); } }); if (drawCachedBitmapOnly) { drawShadowToScreen(); return; } if (createApptShadows) { //Make a list of actions. We will process these in threads below. List <Action> actions = new List <Action>(); foreach (ContrApptSingle ctrl in ListContrApptSingles) { if (listAptNumsOnlyRedraw != null && !listAptNumsOnlyRedraw.Contains(ctrl.AptNum)) { continue; } actions.Add(new Action(() => { ctrl.CreateShadow(); })); } if (isThreaded) //Spread the workload over a group of threads. { ODThread.RunParallel(actions, TimeSpan.FromMinutes(1)); } else //Syncronous. { actions.ForEach(x => x()); } } using (Graphics g = Graphics.FromImage(_shadow)) { if (drawSheetBackground) //Draw background first. { ApptDrawing.DrawAllButAppts(g, true, new DateTime(2011, 1, 1, 0, 0, 0), new DateTime(2011, 1, 1, 0, 0, 0), ApptDrawing.VisOps.Count, 0, 8, false); } foreach (ContrApptSingle ctrl in ListContrApptSingles) { //Filter based on AptNum where applicable. if (listAptNumsOnlyRedraw != null && !listAptNumsOnlyRedraw.Contains(ctrl.AptNum)) { continue; } //Make sure that appointment shadow was created one way or another. if (!ctrl.IsShadowValid) { continue; } if (ctrl.Location.X >= ApptDrawing.TimeWidth + (ApptDrawing.ProvWidth * ApptDrawing.ProvCount) && ctrl.Width > 3) { g.DrawImage(ctrl.Shadow, ctrl.Location.X, ctrl.Location.Y); } //We are done with these so get rid of them. ctrl.DisposeShadow(); } } if (drawToScreen) { drawShadowToScreen(); } }