Just now I noticed that Visual Studio shows a message box with details when a property is set to an invalid value. For example:
刚才我注意到,当属性设置为无效值时,Visual Studio会显示一个带有详细信息的消息框。例如:
Is it possible to make this type of message box in WinForms?
是否可以在WinForms中生成这种类型的消息框?
I have tried the following code:
我试过以下代码:
MessageBox.Show("Error in Division Fill.\n" + ex.Message,
"Information",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxOptions.RightAlign);
But this produced the following error:
但是这产生了以下错误:
Error 24 The best overloaded method match for 'System.Windows.Forms.MessageBox.Show(string, string, System.Windows.Forms.MessageBoxButtons, System.Windows.Forms.MessageBoxIcon, System.Windows.Forms.MessageBoxDefaultButton)' has some invalid arguments
错误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
G:\ Jagadeeswaran \ 11月17日\ MCS-SPS学校\ MCS-SPS学校\证书\ Transfer.cs 164 21 MCS-SPS学校
How can I fix this error and get a message box that shows additional details?
如何修复此错误并获取显示其他详细信息的消息框?
6 个解决方案
#1
24
As others have pointed out, you should write a custom dialog with the desired features. For help on this, you can look at the actual implementation used by the PropertyGrid
for this dialog (perhaps with a decompiler) , which is, as of .NET 4.0, the System.Windows.Forms.PropertyGridInternal.GridErrorDlg
type, internal to the System.Windows.Forms
assembly.
正如其他人指出的那样,您应该编写一个包含所需功能的自定义对话框。有关这方面的帮助,您可以查看PropertyGrid用于此对话框的实际实现(可能使用反编译器),从.NET 4.0开始,System.Windows.Forms.PropertyGridInternal.GridErrorDlg类型,内部为System.Windows.Forms程序集。
I really wouldn't recommend it (could break in a future release), but if you're feeling really lazy, you can directly use this internal type using reflection.
我真的不推荐它(可以在将来的版本中破解),但是如果你感觉很懒,你可以直接使用反射这种内部类型。
// 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();
Result:
结果:
#2
10
You need to set following properties of Form to create a custom Dialog/Message window.
您需要设置Form的以下属性以创建自定义对话框/消息窗口。
- AcceptButton
- 的AcceptButton
- CancelButton
- CancelButton
- FormBorderStyle=FixedDialog
- FormBorderStyle = FixedDialog
- MaximizeBox=False
- MaximizeBox = FALSE
- MinimizeBox=False
- MinimizeBox = FALSE
- ShowIcon=False
- ShowIcon =假
- ShowInTaskBar=False
- ShowInTaskBar =假
- StartPosition=CenterParent
- 中StartPosition = CenterParent
Now, use ShowDialog() method to show custom dialog.
现在,使用ShowDialog()方法显示自定义对话框。
MyDialog dialog=new MyDialog();
DialogResult result=dialog.ShowDialog();
if(result == DialogResult.OK)
{
//
}
For more information on Dialog read MSDN article - Dialog Boxes (Visual C#)
有关Dialog read MSDN文章的更多信息 - 对话框(Visual C#)
#3
3
just write your own dialog, there is no overload like you want to show method.
只是编写自己的对话框,没有像你想要显示方法那样的重载。
#4
1
Based of @AVD's answer above (which I upvoted) I wrote the following. Paste this into a form you generated using a VS template and it should work, maybe with few tweaks.
基于@ AVD上面的答案(我赞成),我写了以下内容。将其粘贴到您使用VS模板生成的表单中,它应该可以工作,可能只需要很少的调整。
My code:
我的代码:
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);
}
}
Designer auto generated code (it should give you an idea regarding what to put in the form if you don't want to paste it):
设计器自动生成的代码(如果您不想粘贴它,它应该让您知道如何放入表单中):
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;
}
}
#5
0
You can simply do this:
你可以这样做:
catch (Exception error)
{
throw new Exception("Error with details button! \n"+error);
}
The text in "" is "Adicionar Fotografia".
“”中的文字是“Adicionar Fotografia”。
Note: this code works fine when running the app(.exe) while running in editor it doesn't work and makes sense.
注意:此代码在运行应用程序(.exe)时工作正常,而在编辑器中运行它不起作用并且有意义。
This is an example of the code above
这是上面代码的一个例子
#6
0
I also encounter the same problem to you. I suggest you use windowsAPIcode pack. This site will be a great help. Just follow the instructions properly: http://www.developerfusion.com/article/71793/windows-7-task-dialogs/
我也遇到了同样的问题。我建议你使用windowsAPIcode包。这个网站将是一个很大的帮助。请按照说明正确操作:http://www.developerfusion.com/article/71793/windows-7-task-dialogs/
#1
24
As others have pointed out, you should write a custom dialog with the desired features. For help on this, you can look at the actual implementation used by the PropertyGrid
for this dialog (perhaps with a decompiler) , which is, as of .NET 4.0, the System.Windows.Forms.PropertyGridInternal.GridErrorDlg
type, internal to the System.Windows.Forms
assembly.
正如其他人指出的那样,您应该编写一个包含所需功能的自定义对话框。有关这方面的帮助,您可以查看PropertyGrid用于此对话框的实际实现(可能使用反编译器),从.NET 4.0开始,System.Windows.Forms.PropertyGridInternal.GridErrorDlg类型,内部为System.Windows.Forms程序集。
I really wouldn't recommend it (could break in a future release), but if you're feeling really lazy, you can directly use this internal type using reflection.
我真的不推荐它(可以在将来的版本中破解),但是如果你感觉很懒,你可以直接使用反射这种内部类型。
// 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();
Result:
结果:
#2
10
You need to set following properties of Form to create a custom Dialog/Message window.
您需要设置Form的以下属性以创建自定义对话框/消息窗口。
- AcceptButton
- 的AcceptButton
- CancelButton
- CancelButton
- FormBorderStyle=FixedDialog
- FormBorderStyle = FixedDialog
- MaximizeBox=False
- MaximizeBox = FALSE
- MinimizeBox=False
- MinimizeBox = FALSE
- ShowIcon=False
- ShowIcon =假
- ShowInTaskBar=False
- ShowInTaskBar =假
- StartPosition=CenterParent
- 中StartPosition = CenterParent
Now, use ShowDialog() method to show custom dialog.
现在,使用ShowDialog()方法显示自定义对话框。
MyDialog dialog=new MyDialog();
DialogResult result=dialog.ShowDialog();
if(result == DialogResult.OK)
{
//
}
For more information on Dialog read MSDN article - Dialog Boxes (Visual C#)
有关Dialog read MSDN文章的更多信息 - 对话框(Visual C#)
#3
3
just write your own dialog, there is no overload like you want to show method.
只是编写自己的对话框,没有像你想要显示方法那样的重载。
#4
1
Based of @AVD's answer above (which I upvoted) I wrote the following. Paste this into a form you generated using a VS template and it should work, maybe with few tweaks.
基于@ AVD上面的答案(我赞成),我写了以下内容。将其粘贴到您使用VS模板生成的表单中,它应该可以工作,可能只需要很少的调整。
My code:
我的代码:
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);
}
}
Designer auto generated code (it should give you an idea regarding what to put in the form if you don't want to paste it):
设计器自动生成的代码(如果您不想粘贴它,它应该让您知道如何放入表单中):
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;
}
}
#5
0
You can simply do this:
你可以这样做:
catch (Exception error)
{
throw new Exception("Error with details button! \n"+error);
}
The text in "" is "Adicionar Fotografia".
“”中的文字是“Adicionar Fotografia”。
Note: this code works fine when running the app(.exe) while running in editor it doesn't work and makes sense.
注意:此代码在运行应用程序(.exe)时工作正常,而在编辑器中运行它不起作用并且有意义。
This is an example of the code above
这是上面代码的一个例子
#6
0
I also encounter the same problem to you. I suggest you use windowsAPIcode pack. This site will be a great help. Just follow the instructions properly: http://www.developerfusion.com/article/71793/windows-7-task-dialogs/
我也遇到了同样的问题。我建议你使用windowsAPIcode包。这个网站将是一个很大的帮助。请按照说明正确操作:http://www.developerfusion.com/article/71793/windows-7-task-dialogs/