先來看提示框,可以看到框其實是一個去掉最大化、最小化按鈕後的窗體,窗體的內容就是我們想要提示的內容,重繪提示框其實就是重繪窗體以及中間部分的內容。
首先重繪窗體,訊息提示框的窗體不是XtraForm而是XtraMessageBoxForm,重寫CreateFormBorderPainter()方法。
internal class MessageBoxForm : XtraMessageBoxForm { protected override FormPainter CreateFormBorderPainter() { return new MessageBoxFormPainter(this, LookAndFeel); } }
MessageBoxFormPainter繼承於FormPainter,窗體樣式由此類繪製。窗體可重繪的部分包括窗體邊框,border(邊框)、caption(標題欄)、Frame(提示框中間部分和提示框左下右邊之間部分)但不包括中間內容部分。重繪需要用GraphicsCache對選定區域進行重繪(Rectangle),如標題文字框(TextBounds)、標題欄框(CaptionBounds)等等。詳細見下:
internal class MessageBoxFormPainter : FormPainter { internal MessageBoxFormPainter(Control owner, ISkinProvider provider) : base(owner, provider) { } /// <summary> /// 標題文字樣式 /// </summary> /// <param name="cache"></param> protected override void DrawText(GraphicsCache cache) { string text = Text; if (text == null || text.Length == 0 || TextBounds.IsEmpty) return; AppearanceObject appearance = new AppearanceObject(GetDefaultAppearance()); appearance.Font = Owner.Font; appearance.TextOptions.Trimming = Trimming.EllipsisCharacter; Rectangle r = RectangleHelper.GetCenterBounds(TextBounds, new Size(TextBounds.Width, appearance.CalcDefaultTextSize(cache.Graphics).Height)); DrawTextShadow(cache, appearance, r); //cache.DrawString(text, appearance.Font, appearance.GetForeBrush(cache),r, appearance.GetStringFormat()); cache.DrawString(text, appearance.Font, Color.Blue, r, appearance.GetStringFormat()); // 字型顏色、樣式 } /// <summary> /// 標題陰影 /// </summary> /// <param name="cache"></param> /// <param name="appearance"></param> /// <param name="bounds"></param> protected override void DrawTextShadow(GraphicsCache cache, AppearanceObject appearance, Rectangle bounds) { base.DrawTextShadow(cache, appearance, bounds); } /// <summary> /// 標題文字框高度 /// </summary> /// <param name="cache"></param> /// <param name="appearance"></param> /// <returns></returns> protected override int CalcTextHeight(GraphicsCache cache, AppearanceObject appearance) { return (int)(cache.Graphics.MeasureString(Text, Owner.Font).Height); } /// <summary> /// 標題欄高度 /// </summary> /// <returns></returns> protected override int GetCaptionHeight() { return 30; } /// <summary> /// 畫標題 /// </summary> /// <param name="cache"></param> /// <param name="doubleBuffer"></param> protected override void DrawCaption(GraphicsCache cache, bool doubleBuffer) { base.DrawCaption(cache, doubleBuffer); } /// <summary> /// 畫背景 /// </summary> /// <param name="cache"></param> protected override void DrawBackground(GraphicsCache cache) { base.DrawBackground(cache); Rectangle r = RectangleHelper.GetCenterBounds(this.CaptionBounds, new Size(CaptionBounds.Width, CaptionBounds.Height)); Brush linGrBrush = new LinearGradientBrush(r, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 0, 0, 255), 45); cache.FillRectangle(linGrBrush, r); } /// <summary> /// 畫邊框 /// </summary> /// <param name="cache"></param> /// <param name="doubleBuffer"></param> protected override void DrawBorders(GraphicsCache cache, bool doubleBuffer) { base.DrawBorders(cache, doubleBuffer); //Rectangle r = RectangleHelper.GetCenterBounds(this.CaptionBounds, new Size(CaptionBounds.Width, CaptionBounds.Height)); //Pen myPen = new Pen(Color.Black, 1); //cache.DrawRectangle(myPen, r); } /// <summary> /// 畫展示內容周邊(左、右、下部分) /// </summary> /// <param name="cache"></param> /// <param name="info"></param> /// <param name="kind">表示周邊為左、右、下的哪一個</param> protected override void DrawFrameCore(GraphicsCache cache, SkinElementInfo info, FrameKind kind) { base.DrawFrameCore(cache, info, kind); Brush linGrBrush = new LinearGradientBrush(info.Bounds, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 0, 0, 255), 45); //Color.FromArgb(255, 119, 144, 237), //Color.FromArgb(255, 180, 154, 202), 45); cache.FillRectangle(linGrBrush, info.Bounds); } /// <summary> /// 畫標題文字前圖示 /// </summary> /// <param name="cache"></param> public override void DrawIcon(GraphicsCache cache) { base.DrawIcon(cache); //cache.DrawIcon(SystemIcons.Warning,IconBounds); } /// <summary> /// 畫標題欄按鈕(最大化、最小化、關閉) /// </summary> /// <param name="cache"></param> /// <param name="useClip"></param> public override void DrawButtons(GraphicsCache cache, bool useClip) { //base.DrawButtons(cache, useClip); this.Buttons.Clear(); } }
最後新建一個類NewXtraMessageBox,寫一個用於彈出窗體的方法,返回值為DialogResult。
private static DialogResult ShowInternal(Control owner, string message, string caption, Icon messageIcon, params DialogResult[] dialogResults) { MessageBoxForm form = new MessageBoxForm(); XtraMessageBoxArgs args = new XtraMessageBoxArgs(owner, message, caption, dialogResults, messageIcon, 0); args.Showing += Args_Showing; return form.ShowMessageBoxDialog(args); }
XtraMessageBoxArgs便是提示框展示的內容部分,註冊Args_Showing事件,在事件重繪窗體。這裡也能重繪窗體,但能重繪的部分只包括在正常設計窗體時的屬性部分(字型大小、邊框樣式、透明度等),提示框中間部分樣式只能在此處修改。
/// <summary> /// 此處修改form和button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void Args_Showing(object sender, XtraMessageShowingArgs e) { //改變form相關樣式 e.Form.Font = new Font("Arial", 14F); e.Form.LookAndFeel.UseDefaultLookAndFeel = false; e.Form.LookAndFeel.Style = DevExpress.LookAndFeel.LookAndFeelStyle.Skin; //e.Form.FormBorderStyle = FormBorderStyle.None; MessageButtonCollection buttons = e.Buttons; SimpleButton btn = null; foreach (var dialog in (DialogResult[])Enum.GetValues(typeof(DialogResult))) { btn = buttons[dialog]; if (btn != null) { btn.Size = new Size(Convert.ToInt32(btn.Width * 1.2), Convert.ToInt32(btn.Height * 1.2)); //按鈕大小 btn.Font = e.Form.Font; //按鈕字型 btn.ShowFocusRectangle = DefaultBoolean.False; } if (dialog == DialogResult.OK) //通過DialogResult確定按鈕並改變具體按鈕樣式 { btn.Text = "‘是’按鈕"; } } } }
最後在此類中寫Show方法,輸入標題、內容、按鈕型別、圖示等資訊呼叫ShowInternal方法,可自定義圖示。
public static void Show(string message) { ShowMessageBox(message, null, MessageBoxButtons.OK, null); } public static void Show(Control owner, string message) { ShowInternal(owner, message, null, null, DialogResult.OK); } public static void Show(string message, string caption) { ShowMessageBox(message, caption, MessageBoxButtons.OK, null); } public static void Show(string message, string caption, MessageBoxButtons messageBox) { ShowMessageBox(message, caption, messageBox, null); } public static void Show(string message, string caption, MessageBoxIcon messageBoxIcon) { if (messageBoxIcon == MessageBoxIcon.Warning) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Warning); } else if (messageBoxIcon == MessageBoxIcon.Question) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Question); } else if (messageBoxIcon == MessageBoxIcon.Error) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Error); } else if (messageBoxIcon == MessageBoxIcon.Information) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Information); } else if (messageBoxIcon == MessageBoxIcon.Asterisk) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Asterisk); } else if (messageBoxIcon == MessageBoxIcon.Exclamation) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Exclamation); } else if (messageBoxIcon == MessageBoxIcon.Hand) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Hand); } else { ShowMessageBox(message, caption, MessageBoxButtons.OK, null); } } public static void Show(string message, string caption, Icon icon) { ShowMessageBox(message, caption, MessageBoxButtons.OK, icon); } public static void Show(string message, string caption, MessageBoxButtons messageBox, MessageBoxIcon messageBoxIcon) { if (messageBoxIcon == MessageBoxIcon.Warning) { ShowMessageBox(message, caption, messageBox, SystemIcons.Warning); } else if (messageBoxIcon == MessageBoxIcon.Question) { ShowMessageBox(message, caption, messageBox, SystemIcons.Question); } else if (messageBoxIcon == MessageBoxIcon.Error) { ShowMessageBox(message, caption, messageBox, SystemIcons.Error); } else if (messageBoxIcon == MessageBoxIcon.Information) { ShowMessageBox(message, caption, messageBox, SystemIcons.Information); } else if (messageBoxIcon == MessageBoxIcon.Asterisk) { ShowMessageBox(message, caption, messageBox, SystemIcons.Asterisk); } else if (messageBoxIcon == MessageBoxIcon.Exclamation) { ShowMessageBox(message, caption, messageBox, SystemIcons.Exclamation); } else if (messageBoxIcon == MessageBoxIcon.Hand) { ShowMessageBox(message, caption, messageBox, SystemIcons.Hand); } else { ShowMessageBox(message, caption, messageBox, null); } } public static void Show(string message, string caption, MessageBoxButtons messageBox, Icon icon) { ShowMessageBox(message, caption, messageBox, icon); } private static void ShowMessageBox(string message, string caption, MessageBoxButtons messageBox, Icon icon) { if (messageBox == MessageBoxButtons.OK) { ShowInternal(null, message, caption, icon, DialogResult.OK); } else if (messageBox == MessageBoxButtons.OKCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.OK, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.YesNo) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Yes, DialogResult.No }); } else if (messageBox == MessageBoxButtons.YesNoCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Yes, DialogResult.No, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.RetryCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Retry, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.AbortRetryIgnore) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Abort, DialogResult.Retry, DialogResult.Ignore }); } }
效果如下:
通過重繪可以還可將背景改為圖片、改變按鈕位置等等、可進一步擴充。
完整專案可以從我的csdn下載:https://download.csdn.net/download/weixin_52748738/18149812
附完整程式碼:
using DevExpress.Skins; using DevExpress.Skins.XtraForm; using DevExpress.Utils; using DevExpress.Utils.Drawing; using DevExpress.XtraEditors; using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace TestMessageBox { public static class NewMessageBox { #region show部分 public static void Show(string message) { ShowMessageBox(message, null, MessageBoxButtons.OK, null); } public static void Show(Control owner, string message) { ShowInternal(owner, message, null, null, DialogResult.OK); } public static void Show(string message, string caption) { ShowMessageBox(message, caption, MessageBoxButtons.OK, null); } public static void Show(string message, string caption, MessageBoxButtons messageBox) { ShowMessageBox(message, caption, messageBox, null); } public static void Show(string message, string caption, MessageBoxIcon messageBoxIcon) { if (messageBoxIcon == MessageBoxIcon.Warning) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Warning); } else if (messageBoxIcon == MessageBoxIcon.Question) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Question); } else if (messageBoxIcon == MessageBoxIcon.Error) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Error); } else if (messageBoxIcon == MessageBoxIcon.Information) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Information); } else if (messageBoxIcon == MessageBoxIcon.Asterisk) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Asterisk); } else if (messageBoxIcon == MessageBoxIcon.Exclamation) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Exclamation); } else if (messageBoxIcon == MessageBoxIcon.Hand) { ShowMessageBox(message, caption, MessageBoxButtons.OK, SystemIcons.Hand); } else { ShowMessageBox(message, caption, MessageBoxButtons.OK, null); } } public static void Show(string message, string caption, Icon icon) { ShowMessageBox(message, caption, MessageBoxButtons.OK, icon); } public static void Show(string message, string caption, MessageBoxButtons messageBox, MessageBoxIcon messageBoxIcon) { if (messageBoxIcon == MessageBoxIcon.Warning) { ShowMessageBox(message, caption, messageBox, SystemIcons.Warning); } else if (messageBoxIcon == MessageBoxIcon.Question) { ShowMessageBox(message, caption, messageBox, SystemIcons.Question); } else if (messageBoxIcon == MessageBoxIcon.Error) { ShowMessageBox(message, caption, messageBox, SystemIcons.Error); } else if (messageBoxIcon == MessageBoxIcon.Information) { ShowMessageBox(message, caption, messageBox, SystemIcons.Information); } else if (messageBoxIcon == MessageBoxIcon.Asterisk) { ShowMessageBox(message, caption, messageBox, SystemIcons.Asterisk); } else if (messageBoxIcon == MessageBoxIcon.Exclamation) { ShowMessageBox(message, caption, messageBox, SystemIcons.Exclamation); } else if (messageBoxIcon == MessageBoxIcon.Hand) { ShowMessageBox(message, caption, messageBox, SystemIcons.Hand); } else { ShowMessageBox(message, caption, messageBox, null); } } public static void Show(string message, string caption, MessageBoxButtons messageBox, Icon icon) { ShowMessageBox(message, caption, messageBox, icon); } private static void ShowMessageBox(string message, string caption, MessageBoxButtons messageBox, Icon icon) { if (messageBox == MessageBoxButtons.OK) { ShowInternal(null, message, caption, icon, DialogResult.OK); } else if (messageBox == MessageBoxButtons.OKCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.OK, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.YesNo) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Yes, DialogResult.No }); } else if (messageBox == MessageBoxButtons.YesNoCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Yes, DialogResult.No, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.RetryCancel) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Retry, DialogResult.Cancel }); } else if (messageBox == MessageBoxButtons.AbortRetryIgnore) { ShowInternal(null, message, caption, icon, new DialogResult[] { DialogResult.Abort, DialogResult.Retry, DialogResult.Ignore }); } } #endregion private static DialogResult ShowInternal(Control owner, string message, string caption, Icon messageIcon, params DialogResult[] dialogResults) { MessageBoxForm form = new MessageBoxForm(); XtraMessageBoxArgs args = new XtraMessageBoxArgs(owner, message, caption, dialogResults, messageIcon, 0); args.Showing += Args_Showing; return form.ShowMessageBoxDialog(args); } /// <summary> /// 此處修改form和button /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void Args_Showing(object sender, XtraMessageShowingArgs e) { e.Form.Font = new Font("Arial", 14F); e.Form.LookAndFeel.UseDefaultLookAndFeel = false; e.Form.LookAndFeel.Style = DevExpress.LookAndFeel.LookAndFeelStyle.Skin; //e.Form.FormBorderStyle = FormBorderStyle.None; MessageButtonCollection buttons = e.Buttons; SimpleButton btn = null; foreach (var dialog in (DialogResult[])Enum.GetValues(typeof(DialogResult))) { btn = buttons[dialog]; if (btn != null) { btn.Size = new Size(Convert.ToInt32(btn.Width * 1.2), Convert.ToInt32(btn.Height * 1.2)); //按鈕大小 btn.Font = e.Form.Font; //按鈕字型 btn.ShowFocusRectangle = DefaultBoolean.False; } if (dialog == DialogResult.OK) { btn.Text = "‘是’按鈕"; } } } } internal class MessageBoxForm : XtraMessageBoxForm { protected override FormPainter CreateFormBorderPainter() { return new MessageBoxFormPainter(this, LookAndFeel); } } internal class MessageBoxFormPainter : FormPainter { internal MessageBoxFormPainter(Control owner, ISkinProvider provider) : base(owner, provider) { } /// <summary> /// 標題文字樣式 /// </summary> /// <param name="cache"></param> protected override void DrawText(GraphicsCache cache) { string text = Text; if (text == null || text.Length == 0 || TextBounds.IsEmpty) return; AppearanceObject appearance = new AppearanceObject(GetDefaultAppearance()); appearance.Font = Owner.Font; appearance.TextOptions.Trimming = Trimming.EllipsisCharacter; Rectangle r = RectangleHelper.GetCenterBounds(TextBounds, new Size(TextBounds.Width, appearance.CalcDefaultTextSize(cache.Graphics).Height)); DrawTextShadow(cache, appearance, r); //cache.DrawString(text, appearance.Font, appearance.GetForeBrush(cache),r, appearance.GetStringFormat()); cache.DrawString(text, appearance.Font, Color.Blue, r, appearance.GetStringFormat()); // 字型顏色、樣式 } /// <summary> /// 標題陰影 /// </summary> /// <param name="cache"></param> /// <param name="appearance"></param> /// <param name="bounds"></param> protected override void DrawTextShadow(GraphicsCache cache, AppearanceObject appearance, Rectangle bounds) { base.DrawTextShadow(cache, appearance, bounds); } /// <summary> /// 標題文字框高度 /// </summary> /// <param name="cache"></param> /// <param name="appearance"></param> /// <returns></returns> protected override int CalcTextHeight(GraphicsCache cache, AppearanceObject appearance) { return (int)(cache.Graphics.MeasureString(Text, Owner.Font).Height); } /// <summary> /// 標題欄高度 /// </summary> /// <returns></returns> protected override int GetCaptionHeight() { return 30; } /// <summary> /// 畫標題 /// </summary> /// <param name="cache"></param> /// <param name="doubleBuffer"></param> protected override void DrawCaption(GraphicsCache cache, bool doubleBuffer) { base.DrawCaption(cache, doubleBuffer); } /// <summary> /// 畫背景 /// </summary> /// <param name="cache"></param> protected override void DrawBackground(GraphicsCache cache) { base.DrawBackground(cache); Rectangle r = RectangleHelper.GetCenterBounds(this.CaptionBounds, new Size(CaptionBounds.Width, CaptionBounds.Height)); Brush linGrBrush = new LinearGradientBrush(r, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 0, 0, 255), 45); cache.FillRectangle(linGrBrush, r); } /// <summary> /// 畫邊框 /// </summary> /// <param name="cache"></param> /// <param name="doubleBuffer"></param> protected override void DrawBorders(GraphicsCache cache, bool doubleBuffer) { base.DrawBorders(cache, doubleBuffer); //Rectangle r = RectangleHelper.GetCenterBounds(this.CaptionBounds, new Size(CaptionBounds.Width, CaptionBounds.Height)); //Pen myPen = new Pen(Color.Black, 1); //cache.DrawRectangle(myPen, r); } /// <summary> /// 畫展示內容周邊(左、右、下部分) /// </summary> /// <param name="cache"></param> /// <param name="info"></param> /// <param name="kind">表示周邊為左、右、下的哪一個</param> protected override void DrawFrameCore(GraphicsCache cache, SkinElementInfo info, FrameKind kind) { base.DrawFrameCore(cache, info, kind); Brush linGrBrush = new LinearGradientBrush(info.Bounds, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 0, 0, 255), 45); //Color.FromArgb(255, 119, 144, 237), //Color.FromArgb(255, 180, 154, 202), 45); cache.FillRectangle(linGrBrush, info.Bounds); } /// <summary> /// 畫標題文字前圖示 /// </summary> /// <param name="cache"></param> public override void DrawIcon(GraphicsCache cache) { base.DrawIcon(cache); //cache.DrawIcon(SystemIcons.Warning,IconBounds); } /// <summary> /// 畫標題欄按鈕(最大化、最小化、關閉) /// </summary> /// <param name="cache"></param> /// <param name="useClip"></param> public override void DrawButtons(GraphicsCache cache, bool useClip) { //base.DrawButtons(cache, useClip); this.Buttons.Clear(); } } }