[DEVEXPRESS/WINFORM] SplashScreenManager 클래스 : ShowOverlayForm 메소드를 사용해 오버레이 폼 표시하기
DevExpress/WinForm 2020. 2. 27. 22:07■ SplashScreenManager 클래스 : ShowOverlayForm 메소드를 사용해 오버레이 폼 표시하기
------------------------------------------------------------------------------------------------------------------------
▶ CustomOverlayImagePainter.cs
using System; using System.Drawing; using System.Windows.Forms;
using DevExpress.XtraSplashScreen;
namespace TestProject { /// <summary> /// 커스텀 오버레이 이미지 페인터 /// </summary> public class CustomOverlayImagePainter : OverlayImagePainter { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 소유자 컨트롤 /// </summary> private Control ownerControl;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - CustomOverlayImagePainter(ownerControl, image, hoverImage, Action)
/// <summary> /// 생성자 /// </summary> /// <param name="ownerControl">소유자 컨트롤</param> /// <param name="image">이미지</param> /// <param name="hoverImage">호버 이미지</param> /// <param name="clickAction">클릭 액션</param> public CustomOverlayImagePainter(Control ownerControl, Image image, Image hoverImage = null, Action clickAction = null) : base ( image, hoverImage, clickAction ) { this.ownerControl = ownerControl; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 이미지 경계 계산하기 - CalcImageBounds(e)
/// <summary> /// 이미지 경계 계산하기 /// </summary> /// <param name="e">이벤트 인자</param> /// <returns>이미지 경계</returns> protected override Rectangle CalcImageBounds(OverlayLayeredWindowObjectInfoArgs e) { Rectangle imageRectangle = new Rectangle ( (this.ownerControl.ClientRectangle.Width - Image.Width ) / 2, (this.ownerControl.ClientRectangle.Height - Image.Height) / 2 - e.ImageBounds.Height, Image.Width, Image.Height );
return imageRectangle; }
#endregion } }
|
▶ CustomOverlayTextPainter.cs
using System.Drawing; using System.Windows.Forms;
using DevExpress.XtraSplashScreen;
namespace TestProject { /// <summary> /// 커스텀 오버레이 텍스트 페인터 /// </summary> public class CustomOverlayTextPainter : OverlayTextPainter { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 소유자 컨트롤 /// </summary> private Control ownerControl;
/// <summary> /// 텍스트 오프셋 /// </summary> private int textOffsetY;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - CustomOverlayTextPainter(ownerControl, font, color, textOffsetY)
/// <summary> /// 생성자 /// </summary> /// <param name="ownerControl">소유자 컨트롤</param> /// <param name="font">폰트</param> /// <param name="color">색상</param> /// <param name="textOffsetY">텍스트 오프셋</param> public CustomOverlayTextPainter(Control ownerControl, Font font, Color color, int textOffsetY) : base() { this.ownerControl = ownerControl;
Font = font; Color = color;
this.textOffsetY = textOffsetY; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 텍스트 경계 계산하기 - CalcTextBounds(e)
/// <summary> /// 텍스트 경계 계산하기 /// </summary> /// <param name="e">이벤트 인자</param> /// <returns>텍스트 경계</returns> protected override Rectangle CalcTextBounds(OverlayLayeredWindowObjectInfoArgs e) { using(Graphics graphics = this.ownerControl.CreateGraphics()) { Size textSize = graphics.MeasureString(Text, Font).ToSize();
Rectangle textRectangle = new Rectangle ( (this.ownerControl.ClientRectangle.Width - textSize.Width ) / 2, (this.ownerControl.ClientRectangle.Height - textSize.Height) / 2 + this.textOffsetY, textSize.Width, textSize.Height );
return textRectangle; } }
#endregion } }
|
▶ OverlayFormHelper.cs
using System; using System.Drawing; using System.Threading; using System.Windows.Forms;
using DevExpress.LookAndFeel; using DevExpress.Skins; using DevExpress.Utils; using DevExpress.Utils.Drawing; using DevExpress.Utils.Svg; using DevExpress.XtraSplashScreen;
namespace TestProject { /// <summary> /// 오버레이 폼 헬퍼 /// </summary> public class OverlayFormHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary> /// 디폴트 폰트 24 /// </summary> public static Font DefaultFont24 = new Font("나눔고딕코딩", 24f);
/// <summary> /// 디폴트 폰트 16 /// </summary> public static Font DefaultFont16 = new Font("나눔고딕코딩", 16f);
/// <summary> /// 디폴트 폰트 12 /// </summary> public static Font DefaultFont12 = new Font("나눔고딕코딩", 12f);
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 취소 버튼 일반 이미지 /// </summary> private static Image _cancelButtonNormalImage;
/// <summary> /// 취소 버튼 활성 이미지 /// </summary> private static Image _cancelButtonActiveImage;
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 오버레이 텍스트 페인터 /// </summary> private OverlayTextPainter overlayTextPainter;
/// <summary> /// 오버레이 이미지 페인터 /// </summary> private OverlayImagePainter overlayImagePainter;
/// <summary> /// 소유자 컨트롤 /// </summary> private Control ownerControl;
/// <summary> /// 텍스트 폰트 /// </summary> private Font textFont;
/// <summary> /// 텍스트 색상 /// </summary> private Color textColor;
/// <summary> /// 취소 토큰 소스 /// </summary> private CancellationTokenSource cancellationTokenSource;
/// <summary> /// 오버레이 윈도우 페인터 /// </summary> private IOverlayWindowPainter overlayWindowPainter;
/// <summary> /// 오버레이 핸들 /// </summary> private IOverlaySplashScreenHandle overlayHandle = null;
/// <summary> /// 텍스트 오프셋 Y /// </summary> private int textOffsetY;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 취소 여부 - IsCancelled
/// <summary> /// 취소 여부 /// </summary> public bool IsCancelled { get { return this.cancellationTokenSource != null && this.cancellationTokenSource.Token.IsCancellationRequested; } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static
#region 생성자 - OverlayFormHelper()
/// <summary> /// 생성자 /// </summary> static OverlayFormHelper() { _cancelButtonNormalImage = GetCancelButtonNormalImage(); _cancelButtonActiveImage = GetCancelButtonActiveImage(); }
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - OverlayFormHelper(ownerControl, textFont, textColor, allowCancel, textOffsetY)
/// <summary> /// 생성자 /// </summary> /// <param name="ownerControl">소유자 컨트롤</param> /// <param name="textFont">텍스트 폰트</param> /// <param name="textColor">텍스트 색상</param> /// <param name="allowCancel">취소 허용 여부</param> /// <param name="textOffsetY">텍스트 오프셋 Y</param> public OverlayFormHelper(Control ownerControl, Font textFont, Color textColor, bool allowCancel, int textOffsetY = 0) { this.ownerControl = ownerControl; this.textFont = textFont; this.textColor = textColor; this.textOffsetY = textOffsetY;
if(allowCancel) { this.cancellationTokenSource = new CancellationTokenSource(); } else { this.cancellationTokenSource = null; }
this.overlayTextPainter = new CustomOverlayTextPainter(this.ownerControl, this.textFont, this.textColor, this.textOffsetY);
if(this.cancellationTokenSource == null) { this.overlayWindowPainter = new OverlayWindowCompositePainter(this.overlayTextPainter); } else { this.overlayImagePainter = new CustomOverlayImagePainter ( this.ownerControl, _cancelButtonNormalImage, _cancelButtonActiveImage, new Action(ProcessClick) );
this.overlayWindowPainter = new OverlayWindowCompositePainter ( this.overlayTextPainter, this.overlayImagePainter ); } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private
#region 이미지 생성하기 - CreateImage(imageByteArray, skinProvider)
/// <summary> /// 이미지 생성하기 /// </summary> /// <param name="imageByteArray">이미지 바이트 배열</param> /// <param name="skinProvider">스킨 제공자</param> /// <returns>이미지</returns> private static Image CreateImage(byte[] imageByteArray, ISkinProvider skinProvider = null) { SvgBitmap svgBitmap = new SvgBitmap(imageByteArray);
return svgBitmap.Render ( SvgPaletteHelper.GetSvgPalette(skinProvider ?? UserLookAndFeel.Default, ObjectState.Normal), ScaleUtils.GetScaleFactor().Height ); }
#endregion #region 취소 버튼 일반 이미지 구하기 - GetCancelButtonNormalImage()
/// <summary> /// 취소 버튼 일반 이미지 구하기 /// </summary> /// <returns>취소 버튼 이미지</returns> private static Image GetCancelButtonNormalImage() { return CreateImage(Properties.Resources.CancelNormal); }
#endregion #region 취소 버튼 활성 이미지 구하기 - GetCancelButtonActiveImage()
/// <summary> /// 취소 버튼 활성 이미지 구하기 /// </summary> /// <returns>활성 취소 버튼 이미지</returns> private static Image GetCancelButtonActiveImage() { return CreateImage(Properties.Resources.CancelActive); }
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Public
#region 표시하기 - Show()
/// <summary> /// 표시하기 /// </summary> public void Show() { this.overlayHandle = SplashScreenManager.ShowOverlayForm ( this.ownerControl, customPainter : this.overlayWindowPainter ); }
#endregion #region 메시지 설정하기 - SetMessage(message)
/// <summary> /// 메시지 설정하기 /// </summary> /// <param name="message">메시지</param> public void SetMessage(string message) { this.overlayTextPainter.Text = message; }
#endregion #region 닫기 - Close()
/// <summary> /// 닫기 /// </summary> public void Close() { SplashScreenManager.CloseOverlayForm(this.overlayHandle);
if(this.cancellationTokenSource != null) { this.cancellationTokenSource.Dispose();
this.cancellationTokenSource = null; } }
#endregion
#region 취소 요청시 예외 발생시키기 - ThrowIfCancellationRequested()
/// <summary> /// 취소 요청시 예외 발생시키기 /// </summary> public void ThrowIfCancellationRequested() { if(this.cancellationTokenSource != null && this.cancellationTokenSource.Token != null) { this.cancellationTokenSource.Token.ThrowIfCancellationRequested(); } }
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region 클릭시 처리하기 - ProcessClick()
/// <summary> /// 클릭시 처리하기 /// </summary> private void ProcessClick() { if(this.cancellationTokenSource != null) { this.cancellationTokenSource.Cancel(); } }
#endregion } }
|
▶ MainForm.cs
using System; using System.Threading.Tasks;
using DevExpress.XtraEditors;
namespace TestProject { /// <summary> /// 메인 폼 /// </summary> public partial class MainForm : XtraForm { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary> /// 생성자 /// </summary> public MainForm() { InitializeComponent();
this.executeButton.Click += executeButton_Click; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private
#region 실행 버튼 클릭시 처리하기 - executeButton_Click(sender, e)
/// <summary> /// 실행 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private async void executeButton_Click(object sender, EventArgs e) { OverlayFormHelper helper = new OverlayFormHelper(this.rootTableLayoutPanel, Font, ForeColor, true);
try { helper.Show();
await Task.Run ( () => {
for(int i = 0; i < 30; i++) { helper.SetMessage($"데이터를 로드하고 있습니다. ({i}/30)");
System.Threading.Thread.Sleep(500);
if(helper.IsCancelled) { XtraMessageBox.Show(this, "작업 취소");
return; } } } ); } finally { helper.Close(); } }
#endregion } }
|
------------------------------------------------------------------------------------------------------------------------
'DevExpress > WinForm' 카테고리의 다른 글
[DEVEXPRESS/WINFORM] RibbonControl 클래스 : 리본 갤러리 바 항목 만들기 (0) | 2020.03.03 |
---|---|
[DEVEXPRESS/WINFORM] UserLookAndFeel 클래스 : SetSkinStyle 메소드를 사용해 스킨 설정하기 (0) | 2020.03.03 |
[DEVEXPRESS/WINFORM] GanttControl 클래스 : 간트 차트 만들기 (0) | 2020.03.02 |
[DEVEXPRESS/WINFORM] RibbonControl 클래스 : 페이지 헤더 영역에 버튼 추가하기 (0) | 2020.03.01 |
[DEVEXPRESS/WINFORM] ImagesAssemblyImageList 클래스 : 내장 아이콘 구하기 (0) | 2020.03.01 |
[DEVEXPRESS/WINFORM] SplashScreenManager 클래스 : ShowOverlayForm 메소드를 사용해 오버레이 폼 표시하기 (0) | 2020.02.27 |
[DEVEXPRESS/WINFORM] TabForm 클래스 : 웹 브라우저 만들기 (0) | 2020.02.27 |
[DEVEXPRESS/WINFORM] BarManager 클래스 : MDI 병합하기 (0) | 2020.02.26 |
[DEVEXPRESS/WINFORM] BarManager 클래스 : 바 항목 링크 추가하기 (0) | 2020.02.25 |
[DEVEXPRESS/WINFORM] BarManager 클래스 : 바 항목 추가하기 (0) | 2020.02.25 |
[DEVEXPRESS/WINFORM] BarManager 클래스 : 바 관리자 생성하기 (0) | 2020.02.25 |
댓글을 달아 주세요