2010-09-17 87 views
15

我正在做C#应用程序,并且我想更改消息框的样式。有没有可能?如何自定义消息框

例如:改变按钮样式,前景色等

+6

坏主意,具有一致外观的消息框很重要。遏制用户的“现在这是什么”响应,并使其有可能实际上阅读邮件并单击正确的按钮。 – 2010-09-17 11:59:02

+1

@Hans Passant:这个问题是为了清楚我对消息框的疑问而给出的,这就是为什么我问“是否可能?” – 2010-09-20 06:16:59

+3

原则上,我同意Hans Passant。我认为消息框应该具有一致的外观和感觉。但是现在意味着什么?毕竟有许多程序有更复杂的消息框,而不是最少的关于框。我想大多数用户不会感到惊讶,如果在不同的程序中的消息框中,按钮样式和前台颜色等变化不大。 – matsolof 2010-09-23 17:42:09

回答

46

不能restyle默认的MessageBox因为这是依赖于当前的Windows操作系统的主题,但是你可以很容易地创建自己的MessageBox。只需添加一个新的形式(即MyNewMessageBox)将项目与这些设置:

FormBorderStyle FixedToolWindow 
ShowInTaskBar  False 
StartPosition  CenterScreen 

表明它使用myNewMessageBoxInstance.ShowDialog();。并添加一个标签和按钮到您的表单,如确定和取消,并适当地设置其对话结果,即添加一个按钮到MyNewMessageBox并称之为btnOK。将属性窗口中的DialogResult属性设置为DialogResult.OK。当按下该按钮将返回OK结果:

MyNewMessageBox myNewMessageBoxInstance = new MyNewMessageBox(); 
DialogResult result = myNewMessageBoxInstance.ShowDialog(); 
if (result == DialogResult.OK) 
{ 
    // etc 
} 

这将是明智的补充,把你需要的文字和其他选项自己的显示方法:

public DialogResult Show(string text, Color foreColour) 
{ 
    lblText.Text = text; 
    lblText.ForeColor = foreColour; 
    return this.ShowDialog(); 
} 
11

MessageBox::Show使用功能从user32.dll,它的样式依赖于Windows,所以你不能改变它,你必须创建你自己的表格

4

这里是创建你自己的消息框所需的代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace MyStuff 
{ 
    public class MyLabel : Label 
    { 
     public static Label Set(string Text = "", Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color()) 
     { 
      Label l = new Label(); 
      l.Text = Text; 
      l.Font = (Font == null) ? new Font("Calibri", 12) : Font; 
      l.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor; 
      l.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor; 
      l.AutoSize = true; 
      return l; 
     } 
    } 
    public class MyButton : Button 
    { 
     public static Button Set(string Text = "", int Width = 102, int Height = 30, Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color()) 
     { 
      Button b = new Button(); 
      b.Text = Text; 
      b.Width = Width; 
      b.Height = Height; 
      b.Font = (Font == null) ? new Font("Calibri", 12) : Font; 
      b.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor; 
      b.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor; 
      b.UseVisualStyleBackColor = (b.BackColor == SystemColors.Control); 
      return b; 
     } 
    } 
    public class MyImage : PictureBox 
    { 
     public static PictureBox Set(string ImagePath = null, int Width = 60, int Height = 60) 
     { 
      PictureBox i = new PictureBox(); 
      if (ImagePath != null) 
      { 
       i.BackgroundImageLayout = ImageLayout.Zoom; 
       i.Location = new Point(9, 9); 
       i.Margin = new Padding(3, 3, 2, 3); 
       i.Size = new Size(Width, Height); 
       i.TabStop = false; 
       i.Visible = true; 
       i.BackgroundImage = Image.FromFile(ImagePath); 
      } 
      else 
      { 
       i.Visible = true; 
       i.Size = new Size(0, 0); 
      } 
      return i; 
     } 
    } 
    public partial class MyMessageBox : Form 
    { 
     private MyMessageBox() 
     { 
      this.panText = new FlowLayoutPanel(); 
      this.panButtons = new FlowLayoutPanel(); 
      this.SuspendLayout(); 
      // 
      // panText 
      // 
      this.panText.Parent = this; 
      this.panText.AutoScroll = true; 
      this.panText.AutoSize = true; 
      this.panText.AutoSizeMode = AutoSizeMode.GrowAndShrink; 
      //this.panText.Location = new Point(90, 90); 
      this.panText.Margin = new Padding(0); 
      this.panText.MaximumSize = new Size(500, 300); 
      this.panText.MinimumSize = new Size(108, 50); 
      this.panText.Size = new Size(108, 50); 
      // 
      // panButtons 
      // 
      this.panButtons.AutoSize = true; 
      this.panButtons.AutoSizeMode = AutoSizeMode.GrowAndShrink; 
      this.panButtons.FlowDirection = FlowDirection.RightToLeft; 
      this.panButtons.Location = new Point(89, 89); 
      this.panButtons.Margin = new Padding(0); 
      this.panButtons.MaximumSize = new Size(580, 150); 
      this.panButtons.MinimumSize = new Size(108, 0); 
      this.panButtons.Size = new Size(108, 35); 
      // 
      // MyMessageBox 
      // 
      this.AutoScaleDimensions = new SizeF(8F, 19F); 
      this.AutoScaleMode = AutoScaleMode.Font; 
      this.ClientSize = new Size(206, 133); 
      this.Controls.Add(this.panButtons); 
      this.Controls.Add(this.panText); 
      this.Font = new Font("Calibri", 12F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); 
      this.FormBorderStyle = FormBorderStyle.FixedSingle; 
      this.Margin = new Padding(4); 
      this.MaximizeBox = false; 
      this.MinimizeBox = false; 
      this.MinimumSize = new Size(168, 132); 
      this.Name = "MyMessageBox"; 
      this.ShowIcon = false; 
      this.ShowInTaskbar = false; 
      this.StartPosition = FormStartPosition.CenterScreen; 
      this.ResumeLayout(false); 
      this.PerformLayout(); 
     } 
     public static string Show(Label Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      List<Label> Labels = new List<Label>(); 
      Labels.Add(Label); 
      return Show(Labels, Title, Buttons, Image); 
     } 
     public static string Show(string Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      List<Label> Labels = new List<Label>(); 
      Labels.Add(MyLabel.Set(Label)); 
      return Show(Labels, Title, Buttons, Image); 
     } 
     public static string Show(List<Label> Labels = null, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      if (Labels == null) Labels = new List<Label>(); 
      if (Labels.Count == 0) Labels.Add(MyLabel.Set("")); 
      if (Buttons == null) Buttons = new List<Button>(); 
      if (Buttons.Count == 0) Buttons.Add(MyButton.Set("OK")); 
      List<Button> buttons = new List<Button>(Buttons); 
      buttons.Reverse(); 

      int ImageWidth = 0; 
      int ImageHeight = 0; 
      int LabelWidth = 0; 
      int LabelHeight = 0; 
      int ButtonWidth = 0; 
      int ButtonHeight = 0; 
      int TotalWidth = 0; 
      int TotalHeight = 0; 

      MyMessageBox mb = new MyMessageBox(); 

      mb.Text = Title; 

      //Image 
      if (Image != null) 
      { 
       mb.Controls.Add(Image); 
       Image.MaximumSize = new Size(150, 300); 
       ImageWidth = Image.Width + Image.Margin.Horizontal; 
       ImageHeight = Image.Height + Image.Margin.Vertical; 
      } 

      //Labels 
      List<int> il = new List<int>(); 
      mb.panText.Location = new Point(9 + ImageWidth, 9); 
      foreach (Label l in Labels) 
      { 
       mb.panText.Controls.Add(l); 
       l.Location = new Point(200, 50); 
       l.MaximumSize = new Size(480, 2000); 
       il.Add(l.Width); 
      } 
      int mw = Labels.Max(x => x.Width); 
      il.ToString(); 
      Labels.ForEach(l => l.MinimumSize = new Size(Labels.Max(x => x.Width), 1)); 
      mb.panText.Height = Labels.Sum(l => l.Height); 
      mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight); 
      mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300); 
      LabelWidth = mb.panText.Width; 
      LabelHeight = mb.panText.Height; 

      //Buttons 
      foreach (Button b in buttons) 
      { 
       mb.panButtons.Controls.Add(b); 
       b.Location = new Point(3, 3); 
       b.TabIndex = Buttons.FindIndex(i => i.Text == b.Text); 
       b.Click += new EventHandler(mb.Button_Click); 
      } 
      ButtonWidth = mb.panButtons.Width; 
      ButtonHeight = mb.panButtons.Height; 

      //Set Widths 
      if (ButtonWidth > ImageWidth + LabelWidth) 
      { 
       Labels.ForEach(l => l.MinimumSize = new Size(ButtonWidth - ImageWidth - mb.ScrollBarWidth(Labels), 1)); 
       mb.panText.Height = Labels.Sum(l => l.Height); 
       mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight); 
       mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300); 
       LabelWidth = mb.panText.Width; 
       LabelHeight = mb.panText.Height; 
      } 
      TotalWidth = ImageWidth + LabelWidth; 

      //Set Height 
      TotalHeight = LabelHeight + ButtonHeight; 

      mb.panButtons.Location = new Point(TotalWidth - ButtonWidth + 9, mb.panText.Location.Y + mb.panText.Height); 

      mb.Size = new Size(TotalWidth + 25, TotalHeight + 47); 
      mb.ShowDialog(); 
      return mb.Result; 
     } 

     private FlowLayoutPanel panText; 
     private FlowLayoutPanel panButtons; 
     private int ScrollBarWidth(List<Label> Labels) 
     { 
      return (Labels.Sum(l => l.Height) > 300) ? 23 : 6; 
     } 

     private void Button_Click(object sender, EventArgs e) 
     { 
      Result = ((Button)sender).Text; 
      Close(); 
     } 

     private string Result = ""; 
    } 
} 
4

添加winform到项目中(我把它命名为frmShowMessage),并把这个控制就可以了:

1. Panel  (pnlShowMessage) 
2. Label  (lblMessageText) 
3. PictureBox (pictureBox1) 
4. ImageList (imageList1) 

如下更换新的形式代码:

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Drawing.Drawing2D; 

namespace CostumeMessageBox 
{ 
    public partial class frmShowMessage : Form 
    { 
     Button btnOk = new Button(); //Create object of Button. 
     Button btnCancel = new Button(); 
     Button btnNo = new Button(); 
     Button btnYes = new Button(); 
     public const int WM_NCLBUTTONDOWN = 0xA1; 
     public const int HT_CAPTION = 0x2; 

     [DllImportAttribute("user32.dll")] 
     public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); 
     [DllImport("user32.dll")] 
     public static extern bool ReleaseCapture(); 
     public frmShowMessage() 
     { 
      InitializeComponent(); 
     } 

     /// <summary> 
     /// Here I am overriding Paint method of form object 
     /// and set it's background color as gradient. Here I am 
     /// using LinearGradientBrush class object to make gradient 
     /// color which comes in System.Drawing.Drawing2D namespace. 
     /// </summary> 
     /// <param name="e"></param> 
     protected override void OnPaint(PaintEventArgs e) 
     { 
      base.OnPaint(e); 
      ControlPaint.DrawBorder(e.Graphics, ClientRectangle, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid); 
      //Rectangle rect = this.ClientRectangle; 
      //LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Snow, Color.SeaShell, 60); //LightCyan Lavender LightGray 
      //e.Graphics.FillRectangle(brush, rect); 
      //base.OnPaint(e); 
     } 

     private void frmShowMessage_Load(object sender, EventArgs e) 
     { 
      btnOk.Text = "تایید"; //Here we set text of Button. 
      btnOk.DialogResult = DialogResult.OK; //Set DialogResult property of button. 
      btnOk.FlatStyle = FlatStyle.Popup; //Set flat appearence of button. 
      btnOk.BackColor = Color.Beige; 
      btnOk.FlatAppearance.BorderSize = 0; 

      btnCancel.Text = "انصراف"; 
      btnCancel.DialogResult = DialogResult.Cancel; 
      btnCancel.FlatStyle = FlatStyle.Popup; 
      btnCancel.BackColor = Color.Beige; 
      btnCancel.FlatAppearance.BorderSize = 0; 

      btnNo.Text = "خیر"; 
      btnNo.DialogResult = DialogResult.No; 
      btnNo.FlatStyle = FlatStyle.Popup; 
      btnNo.BackColor = Color.Beige; 
      btnNo.FlatAppearance.BorderSize = 0; 

      btnYes.Text = "بله"; 
      btnYes.DialogResult = DialogResult.Yes; 
      btnYes.FlatStyle = FlatStyle.Popup; 
      btnYes.BackColor = Color.Beige; 
      btnYes.FlatAppearance.BorderSize = 0; 
     } 


     /// <summary> 
     /// setMessage method is used to display message 
     /// on form and it's height adjust automatically. 
     /// I am displaying message in a Label control. 
     /// </summary> 
     /// <param name="messageText">Message which needs to be displayed to user.</param> 
     private void setMessage(string messageText) 
     { 
      int number = Math.Abs(messageText.Length/30); 
      if (number != 0) 
      { 
       lblMessageText.Height = lblRightBorder.Height = number*25; 
       Height = lblMessageText.Height; 
      } 

      lblMessageText.Text = messageText; 
     } 

     /// <summary> 
     /// This method is used to add button on message box. 
     /// </summary> 
     /// <param name="MessageButton">MessageButton is type of enumMessageButton 
     /// through which I get type of button which needs to be displayed.</param> 
     private void addButton(enumMessageButton MessageButton) 
     { 
      switch (MessageButton) 
      { 
       case enumMessageButton.OK: 
        { 
         //If type of enumButton is OK then we add OK button only. 
         btnOk.SetBounds(pnlShowMessage.ClientSize.Width - 80, 5, 75, 25); // Set bounds of button. 
         pnlShowMessage.Controls.Add(btnOk); //Finally Add button control on panel. 
        } 
        break; 
       case enumMessageButton.OKCancel: 
        { 
         btnOk.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnOk); 

         btnCancel.SetBounds((pnlShowMessage.ClientSize.Width - (btnOk.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnCancel); 

        } 
        break; 
       case enumMessageButton.YesNo: 
        { 

         btnNo.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnNo); 

         btnYes.SetBounds((pnlShowMessage.ClientSize.Width - (btnNo.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnYes); 
        } 
        break; 
       case enumMessageButton.YesNoCancel: 
        { 
         btnCancel.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnCancel); 

         btnNo.SetBounds((pnlShowMessage.ClientSize.Width - (btnCancel.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnNo); 

         btnYes.SetBounds((pnlShowMessage.ClientSize.Width - (btnCancel.ClientSize.Width + btnNo.ClientSize.Width + 10 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnYes); 
        } 
        break; 
      } 
     } 

     /// <summary> 
     /// We can use this method to add image on message box. 
     /// I had taken all images in ImageList control so that 
     /// I can eaily add images. Image is displayed in 
     /// PictureBox control. 
     /// </summary> 
     /// <param name="MessageIcon">Type of image to be displayed.</param> 
     private void addIconImage(enumMessageIcon MessageIcon) 
     { 
      switch (MessageIcon) 
      { 
       case enumMessageIcon.Error: 
        pictureBox1.Image = imageList1.Images["Error"]; //Error is key name in imagelist control which uniqly identified images in ImageList control. 
        break; 
       case enumMessageIcon.Information: 
        pictureBox1.Image = imageList1.Images["Information"]; 
        break; 
       case enumMessageIcon.Question: 
        pictureBox1.Image = imageList1.Images["Question"]; 
        break; 
       case enumMessageIcon.Warning: 
        pictureBox1.Image = imageList1.Images["Warning"]; 
        break; 
      } 
     } 

     #region Overloaded Show message to display message box. 

     /// <summary> 
     /// Show method is overloaded which is used to display message 
     /// and this is static method so that we don't need to create 
     /// object of this class to call this method. 
     /// </summary> 
     /// <param name="messageText"></param> 
     internal static DialogResult Show(string messageText) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.setMessage(messageText); 
      frmMessage.addIconImage(enumMessageIcon.Information); 
      frmMessage.addButton(enumMessageButton.OK); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     internal static DialogResult Show(string messageText, string messageTitle) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.Text = messageTitle; 
      frmMessage.setMessage(messageText); 
      frmMessage.addIconImage(enumMessageIcon.Information); 
      frmMessage.addButton(enumMessageButton.OK); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     internal static DialogResult Show(string messageText, string messageTitle, enumMessageIcon messageIcon, 
              enumMessageButton messageButton) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.setMessage(messageText); 
      frmMessage.Text = messageTitle; 
      frmMessage.addIconImage(messageIcon); 
      frmMessage.addButton(messageButton); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     #endregion 


     private void frmShowMessage_MouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button != MouseButtons.Left) return; 
      ReleaseCapture(); 
      SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); 

     } 

    } 

    #region constant defiend in form of enumration which is used in showMessage class. 

    internal enum enumMessageIcon 
    { 
     Error, 
     Warning, 
     Information, 
     Question, 
    } 

    internal enum enumMessageButton 
    { 
     OK, 
     YesNo, 
     YesNoCancel, 
     OKCancel 
    } 

    #endregion 
} 

现在你可以调用您的项目中的Customized MessageBox是这样的:

private void btnQuestion_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Question, enumMessageButton.YesNoCancel); 
    } 

    private void btnInformation_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Information, enumMessageButton.OKCancel); 

    } 

    private void btnError_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Error, enumMessageButton.OK); 
    } 

    private void btnWarning_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Warning, enumMessageButton.YesNo); 

    } 

我忘记了我学到这些的链接。

+0

虽然它缺少包含'InitializeComponent()'函数的表单的部分类。作为示例,这很好,但不能立即执行。 – Nyerguds 2015-11-24 12:10:43

+0

@Nyerguds它假定用户知道这一点。这并不意味着在表格部分完整。 – 2015-11-24 20:05:53