如何在WinForms中显示带有详细信息的消息框?

19

刚刚我注意到,当属性被设置为无效值时,Visual Studio会显示一个带有详细信息的消息框。例如:

在WinForms中是否可能制作这种类型的消息框?

我已经尝试了以下代码:

MessageBox.Show("Error in Division Fill.\n" + ex.Message,
                "Information",            
                MessageBoxButtons.OK,
                MessageBoxIcon.Information,
                MessageBoxOptions.RightAlign);

但这会产生以下错误:

错误24:“System.Windows.Forms.MessageBox.Show(string, string, System.Windows.Forms.MessageBoxButtons, System.Windows.Forms.MessageBoxIcon, System.Windows.Forms.MessageBoxDefaultButton)”的最佳重载方法匹配具有一些无效参数

G:\Jagadeeswaran\Nov 17\MCS-SPS School\MCS-SPS School\Certificate\Transfer.cs 164 21 MCS-SPS School

如何修复此错误并获取显示额外详细信息的消息框?


7
那是一个自定义对话框,你不能使用标准的MessageBox.Show重载方法获取它。 - Cody Gray
谢谢。那么,MessageBoxOptions在其中的使用是什么? - Sagotharan
2
MessageBoxOptions的文档可以在这里找到。我不确定你为什么认为RightAlign与显示“详细信息”有关。它只是使消息框中的文本右对齐,就像在RTL系统上一样。 - Cody Gray
6个回答

28

正如其他人所指出的,您应该编写具有所需功能的自定义对话框。对于此类帮助,您可以查看 PropertyGrid 用于此对话框的实际实现(可能是通过反编译器),这是在 .NET 4.0 中作为 System.Windows.Forms 程序集中的 System.Windows.Forms.PropertyGridInternal.GridErrorDlg 类型内部使用的。

我真的不建议这样做(可能会在将来的版本中出现问题),但是如果您感到非常懒惰,可以使用反射来直接使用此内部类型。

// Get reference to the dialog type.
var dialogTypeName = "System.Windows.Forms.PropertyGridInternal.GridErrorDlg";
var dialogType = typeof(Form).Assembly.GetType(dialogTypeName);

// Create dialog instance.
var dialog = (Form)Activator.CreateInstance(dialogType, new PropertyGrid());

// Populate relevant properties on the dialog instance.
dialog.Text = "Sample Title";
dialogType.GetProperty("Details").SetValue(dialog, "Sample Details", null);
dialogType.GetProperty("Message").SetValue(dialog, "Sample Message", null);

// Display dialog.
var result = dialog.ShowDialog();

结果:

详细信息对话框


2
如果我不想在此消息框中显示取消选项,我该怎么做? - Amit Kumar

10

您需要设置以下Form属性以创建自定义对话框/消息窗口。

  1. AcceptButton
  2. CancelButton
  3. FormBorderStyle=FixedDialog
  4. MaximizeBox=False
  5. MinimizeBox=False
  6. ShowIcon=False
  7. ShowInTaskBar=False
  8. StartPosition=CenterParent

现在,使用ShowDialog()方法显示自定义对话框。

MyDialog dialog=new MyDialog();
DialogResult result=dialog.ShowDialog();
if(result == DialogResult.OK)
{
  //
}

如需有关对话框的更多信息,请阅读 MSDN 文章 - 对话框框 (Visual C#)


1
根据这个答案,我编写了自定义表单。请看这里:https://dev59.com/lGoy5IYBdhLWcg3wScFB#40469355 - gneri

3

只需编写您自己的对话框,没有像您想要展示方法那样的重载。


3
基于我赞同的上面的答案,我写了以下内容。将其粘贴到使用VS模板生成的表单中,它应该可以工作,可能需要进行一些微调。
我的代码:
using System;
using System.Windows.Forms;

namespace MessageBoxWithDetails
{
    /// <summary>
    /// A dialog-style form with optional colapsable details section
    /// </summary>
    public partial class MessageBoxWithDetails : Form
    {
        private const string DetailsFormat = "Details {0}";

    public MessageBoxWithDetails(string message, string title, string details = null)
    {
        InitializeComponent();

        lblMessage.Text = message;
        this.Text = title;

        if (details != null)
        {
            btnDetails.Enabled = true;
            btnDetails.Text = DownArrow;
            tbDetails.Text = details;
        }
    }

    private string UpArrow
    {
        get
        {
            return string.Format(DetailsFormat, char.ConvertFromUtf32(0x25B4));
        }
    }

    private string DownArrow
    {
        get
        {
            return string.Format(DetailsFormat, char.ConvertFromUtf32(0x25BE));
        }
    }

    /// <summary>
    /// Meant to give the look and feel of a regular MessageBox
    /// </summary>
    public static void Show(string message, string title, string details = null)
    {
        new MessageBoxWithDetails(message, title, details).ShowDialog();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        // Change these properties now so the label is rendered so we get its real height
        var height = lblMessage.Height;
        SetMessageBoxHeight(height);
    }

    private void SetMessageBoxHeight(int heightChange)
    {
        this.Height = this.Height + heightChange;
        if (this.Height < 150)
        {
            this.Height = 150;
        }
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void btnDetails_Click(object sender, EventArgs e)
    {
        // Re-anchoring the controls so they stay in their place while the form is resized
        btnCopy.Anchor = AnchorStyles.Top;
        btnClose.Anchor = AnchorStyles.Top;
        btnDetails.Anchor = AnchorStyles.Top;
        tbDetails.Anchor = AnchorStyles.Top;

        tbDetails.Visible = !tbDetails.Visible;
        btnCopy.Visible = !btnCopy.Visible;

        btnDetails.Text = tbDetails.Visible ? UpArrow : DownArrow;

        SetMessageBoxHeight(tbDetails.Visible ? tbDetails.Height + 10 : -tbDetails.Height - 10);
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        Clipboard.SetText(tbDetails.Text);
    }
}

设计师自动生成的代码(如果您不想粘贴,它应该为您提供在表单中放置什么的想法)。
namespace MessageBoxWithDetails
{
    partial class MessageBoxWithDetails
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.btnClose = new System.Windows.Forms.Button();
            this.btnDetails = new System.Windows.Forms.Button();
            this.btnCopy = new System.Windows.Forms.Button();
            this.lblMessage = new System.Windows.Forms.Label();
            this.tbDetails = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // btnClose
            // 
            this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.btnClose.Location = new System.Drawing.Point(267, 37);
            this.btnClose.Name = "btnClose";
            this.btnClose.Size = new System.Drawing.Size(75, 23);
            this.btnClose.TabIndex = 0;
            this.btnClose.Text = "Close";
            this.btnClose.UseVisualStyleBackColor = true;
            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
            // 
            // btnDetails
            // 
            this.btnDetails.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.btnDetails.Enabled = false;
            this.btnDetails.Location = new System.Drawing.Point(12, 37);
            this.btnDetails.Name = "btnDetails";
            this.btnDetails.Size = new System.Drawing.Size(75, 23);
            this.btnDetails.TabIndex = 1;
            this.btnDetails.Text = "Details";
            this.btnDetails.UseVisualStyleBackColor = true;
            this.btnDetails.Click += new System.EventHandler(this.btnDetails_Click);
            // 
            // btnCopy
            // 
            this.btnCopy.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.btnCopy.Location = new System.Drawing.Point(93, 37);
            this.btnCopy.Name = "btnCopy";
            this.btnCopy.Size = new System.Drawing.Size(102, 23);
            this.btnCopy.TabIndex = 4;
            this.btnCopy.Text = "Copy To Clipboard";
            this.btnCopy.UseVisualStyleBackColor = true;
            this.btnCopy.Visible = false;
            this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click);
            // 
            // lblMessage
            // 
            this.lblMessage.AutoSize = true;
            this.lblMessage.Location = new System.Drawing.Point(12, 9);
            this.lblMessage.MaximumSize = new System.Drawing.Size(310, 0);
            this.lblMessage.Name = "lblMessage";
            this.lblMessage.Size = new System.Drawing.Size(35, 13);
            this.lblMessage.TabIndex = 5;
            this.lblMessage.Text = "label1";
            // 
            // tbDetails
            // 
            this.tbDetails.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
            this.tbDetails.Location = new System.Drawing.Point(12, 68);
            this.tbDetails.MaximumSize = new System.Drawing.Size(328, 100);
            this.tbDetails.Multiline = true;
            this.tbDetails.Name = "tbDetails";
            this.tbDetails.ReadOnly = true;
            this.tbDetails.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.tbDetails.Size = new System.Drawing.Size(328, 100);
            this.tbDetails.TabIndex = 6;
            this.tbDetails.Visible = false;
            // 
            // MessageBoxWithDetails
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(354, 72);
            this.Controls.Add(this.tbDetails);
            this.Controls.Add(this.lblMessage);
            this.Controls.Add(this.btnCopy);
            this.Controls.Add(this.btnDetails);
            this.Controls.Add(this.btnClose);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "MessageBoxWithDetails";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnClose;
        private System.Windows.Forms.Button btnDetails;
        private System.Windows.Forms.Button btnCopy;
        private System.Windows.Forms.Label lblMessage;
        private System.Windows.Forms.TextBox tbDetails;
    }
}

0

-1
你可以简单地这样做:
catch (Exception error)
{
    throw new Exception("Error with details button! \n"+error);
}

""中的文本是"Adicionar Fotografia"。

注意:当在编辑器中运行时,此代码无法正常工作并且没有意义,但在运行应用程序(.exe)时可以正常工作。

这是上面代码的一个示例:

image


1
虽然这段代码可能回答了问题,但是提供关于为什么和/或如何回答问题的额外上下文可以提高其长期价值。 - ryanyuyu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接