///<summary>It is planned to move some of this logic to OnPaint and use a true double buffer.</summary> public void CreateShadow() { if (this.Parent is ContrApptSheet) { bool isVisible = ApptDrawing.GetIndexOp(OpNum) >= 0; if (!isVisible) { return; } } DisposeShadow(); if (Width < 4) { return; } if (Height < 4) { return; } Shadow = new Bitmap(Width, Height); using (Graphics g = Graphics.FromImage(Shadow)) { ApptSingleDrawing.DrawEntireAppt(g, DataRoww, PatternShowing, Width, Height, IsSelected, ThisIsPinBoard, SelectedAptNum, ApptViewItemL.ApptRows, ApptViewItemL.ApptViewCur, TableApptFields, TablePatFields, 8, false); //In most cases, drawing will be taken care of by ContrApptSheet.DoubleBufferDraw(). //However, BackgroundImage must be set here to draw the bitmap when when dragging. this.BackgroundImage = Shadow; } }
///<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>It is planned to move some of this logic to OnPaint and use a true double buffer.</summary> public void CreateShadow() { if (this.Parent is ContrApptSheet) { bool isVisible = ApptDrawing.GetIndexOp(OpNum) >= 0; if (!isVisible) { return; } } DisposeShadow(); if (Width < 4) { return; } if (Height < 4) { return; } Bitmap shadowNew = new Bitmap(Width, Height); using (Graphics g = Graphics.FromImage(shadowNew)) { ApptSingleDrawing.DrawEntireAppt(g, DataRoww, PatternShowing, Width, Height, IsSelected, ThisIsPinBoard, SelectedAptNum, ApptViewItemL.ApptRows, ApptViewItemL.ApptViewCur, TableApptFields, TablePatFields, 8, false); } //In most cases, drawing will be taken care of by ContrApptSheet.DoubleBufferDraw(). //However, BackgroundImage must be set here to draw the bitmap when when dragging. //If this was inside the using block, a GDI+ exception would sometimes be thrown because the graphics object would still be accessing the //image data when the image reference was changed. Shadow = shadowNew; BackgroundImage = shadowNew; }
///<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(); } }