How can I show message boxes with a «Ding!» sound and a red ‘close’ button in it? This is what I’m talking about:
I’m trying to create some custom errors and warnings, but this:
MessageBox.Show("asdf");
doesn’t seem to give me any customization options.
TylerH
20.8k66 gold badges76 silver badges101 bronze badges
asked Jan 21, 2010 at 13:21
Try this:
MessageBox.Show("Some text", "Some title",
MessageBoxButtons.OK, MessageBoxIcon.Error);
caiosm1005
1,6861 gold badge19 silver badges31 bronze badges
answered Jan 21, 2010 at 13:23
Andrew HareAndrew Hare
345k71 gold badges640 silver badges635 bronze badges
2
Try details: use any option:
MessageBox.Show(
"your message",
"window title",
MessageBoxButtons.OK,
MessageBoxIcon.Warning // for Warning
//MessageBoxIcon.Error // for Error
//MessageBoxIcon.Information // for Information
//MessageBoxIcon.Question // for Question
);
TylerH
20.8k66 gold badges76 silver badges101 bronze badges
answered Jun 30, 2015 at 12:21
MessageBox.Show(
"your message",
"window title",
MessageBoxButtons.OK,
MessageBoxIcon.Asterisk //For Info Asterisk
MessageBoxIcon.Exclamation //For triangle Warning
)
Antonio
19.5k13 gold badges99 silver badges197 bronze badges
answered Jul 8, 2015 at 12:35
You should add namespace if you are not using it:
System.Windows.Forms.MessageBox.Show("Some text", "Some title",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
Alternatively, you can add at the begining of your file:
using System.Windows.Forms
and then use (as stated in previous answers):
MessageBox.Show("Some text", "Some title",
MessageBoxButtons.OK, MessageBoxIcon.Error);
answered Jun 28, 2018 at 14:15
TidesTides
11111 bronze badges
Время на прочтение
4 мин
Количество просмотров 18K
Приветствую!
В статье посвященной моему профайлеру для Entity Framework-a, я вкратце описал примененную мной форму для сообщения пользователю об исключительной ошибке в приложении. После оценки количества скачиваний примера кода, было решено выделить этот пример в отдельный проект, а также добавить поддержку WPF приложений.
Исходники библиотеки вместе с примерами опубликованы на CodePlex под свободной лицензией MIT: https://uiexceptionhandler.codeplex.com/
Подробности под катом.
Введение
Всем известно, что приложения периодически падают по самым разным причинам, при этом, крайне желательно показывать пользователю дружественное сообщение об ошибке в приложении, вместо стандартного сообщения Windows.
Что получилось
При подключенной библиотеке, в случае падения приложения будет показано следующие сообщение с просьбой добавить описание шагов которые привели к ошибке и свой email для ответа, при этом текст ошибки сохраняется в лог файл.
При клике по кнопке «Error detail information» выводиться дополнительная информация об ошибке:
Кнопка Debug позволяет подключить отладчик Visual Studio.
Кнопка «Send to Developer» отправляет письмо на почту разработчику. В случае ошибки отправки сообщения, пользователю будет предложено самому отправить лог файл разработчику на почту.
Отправленное разработчику сообщение придет в таком виде:
Использование
1. Забрать последнюю версию кода https://uiexceptionhandler.codeplex.com/SourceControl/latest
2. Собрать в Release mode.
3. Из папки «UIExceptionHandlerLibs\Deploy» подключить в проект библиотеку UIExceptionHandlerWinForms.dll в случае WinForms приложения и UIExceptionHandlerWPF.dll в случае WPF приложения.
4. Инициализировать путем вызова статического метода с рядом параметров:
UIException.Start(
string serverSmtp,
int portSmtp,
string passwdSmtp,
string userSmtp,
string programmerEmail,
string fromEmail,
string subject
)
Как это работает
Статический метод UIException.Start подписывает метод HandleError на событие AppDomain.CurrentDomain.UnhandledException:
AppDomain.CurrentDomain.UnhandledException += (sender, e) => HandleError((Exception)e.ExceptionObject);
Метод HandleError:
private static void HandleError(Exception exception)
{
try
{
// запускаем обработчик формы и передаем ему ссылку на форму наследованную от интерфейса IErrorHandlerForm
new ErrorHandlerController(exception, new ErrorHandlerForm()).Run();
}
catch (Exception e)
{
// сохраняем ошибку в лог файл
LogHelper.Logger.Error(e);
// в случае ошибки обработки выводим сообщение с просьбой отправить лог файл разработчику на почту
MessageBox.Show("Error processing exception. Please send log file " + LogHelper.ExceptionLogFileName + " to developer: " + Settings.ProgrammerEmail + " \r\n Exception:" + e);
// спрашиваем нужно ли подключить отладчик
if (MessageBox.Show("Attach debugger? \n Only for developer!!!", "Debugging...", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
Debugger.Launch();
throw;
}
}
finally
{
// обязательно завершаем приложение чтобы windows не вывела стандартное сообщение об ошибке
Environment.Exit(1);
}
}
Интерфейс IErrorHandlerForm:
public interface IErrorHandlerForm
{
event Action OnSendButtonClick;
event Action OnShowErrorLinkClick;
event Action OnLogFileLinkClick;
event Action OnDebugButtonClick;
// меняет высоту формы
void SetHeight(int height);
// задает подробное сообщение об ошибке
string ExceptionInfoText { get; set; }
// получает текст из поля дополнительной информации введенной пользователем
string ExceptionDetailText { get; set; }
// email пользователя для ответа
string ReplyEmail { get; }
void ShowExceptionInfoTextBox(bool isShow);
// выводит информационное сообщение
void ShowInfoMessageBox( string text, string caption);
// выводит диалоговое сообщение
bool ShowQuestionDialog( string text, string caption);
// показывает окно в режиме диалога! необходимо чтобы приложение дожидалось закрытия окна и завершилось в finaly
void ShowViewDialog();
void UpdateContactEmail(string contactEmail);
}
В качестве библиотеки для логгирования используется NLog. Для того чтобы избежать появления лишних xml файлов, вся конфигурация Nlog-а делается в коде:
private static void ConfigureNlog()
{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget();
config.AddTarget("file", fileTarget);
fileTarget.Layout = @"${longdate} ${message}";
fileTarget.FileName = "${basedir}/" + ExceptionLogFileName;
var rule2 = new LoggingRule("*", LogLevel.Trace, fileTarget);
config.LoggingRules.Add(rule2);
LogManager.Configuration = config;
}
Чтобы добиться максимальной простой интеграции в проект, я решил все используемые сборки объединить в одну библиотеку. Делается это при помощи приложения ILMerge, путем добавления скрипта в post-build событие:
if $(ConfigurationName) == Release (
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(SolutionDir)Deploy\$(TargetFileName)" "$(TargetDir)*.dll" /target:dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
)
Послесловие
Данное решение было написано для достаточно крупного проекта, применяется уже более 2-х лет, значительно улучшив процесс исправления ошибок, поскольку о каждом падении приложения узнаешь моментально, без дополнительной нотификации от пользователя.
Надеюсь это все будет кому-то полезно!
Всем спасибо за внимание!
Последнее обновление: 09.11.2016
ErrorProvider не является полноценным визуальным компонентом, тем не менее он позволяет настраивать визуальное отображение ошибок при вводе
пользователя. Этот элемент применяется преимущестенно для проверки и индикации ошибок.
Так, определим на форме два текстовых поля с именами nameBox и ageBox. И далее перетащим с панели инструментов на форму элемент ErrorProvider.
ErrorProvider оторазится под формой, а в окне свойств мы также сможем управлять его свойствами:
Среди его свойств можно выделить следующие:
-
BlinkRate: задает частоту мигания значка ошибки
-
BlinkStyle: задает, когда значок ошибки будет мигать
-
Icon: устанавливает сам значок ошибки. По умолчанию это красный кружок с восклицательным знаком, но можно установить любую
другую иконку.
В коде формы приложения пропишем следующее:
using System; using System.ComponentModel; using System.Windows.Forms; namespace HelloApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); nameBox.Validating += nameBox_Validating; ageBox.Validating += ageBox_Validating; } private void nameBox_Validating(object sender, CancelEventArgs e) { if (String.IsNullOrEmpty(nameBox.Text)) { errorProvider1.SetError(nameBox, "Не указано имя!"); } else if (nameBox.Text.Length < 4) { errorProvider1.SetError(nameBox, "Слишком короткое имя!"); } else { errorProvider1.Clear(); } } private void ageBox_Validating(object sender, CancelEventArgs e) { int age = 0; if (String.IsNullOrEmpty(ageBox.Text)) { errorProvider1.SetError(ageBox, "Не указан возраст!"); } else if (!Int32.TryParse(ageBox.Text, out age)) { errorProvider1.SetError(ageBox, "Некорретный возраст!"); } else { errorProvider1.Clear(); } } } }
Здесь для обоих текстовых полей задано событие Validating, которое срабатывает при вводе пользователя и призвано управлять валидацией вода. Это событие
имеется и у других элементов управления, не только у текстовых полей. В обработчике события Validating мы смотрим на введенный текст, и если он не удовлетворяет условиям,
то с помощью метода errorProvider1.SetError()
для определенного элемента добавляем ошибку. Если все условия соблюдены, то, наоборот, удаляем все ошибки
с помощью метода errorProvider1.Clear()
.
Запустим приложение и при некорректном вводе мы увидим ошибку:
Здесь есть небольшая деталь — валидация элемента будет происходить, когда мы завершим ввод и перейдем на другой элемент. Если же нам надо валидировать
элемент по мере ввода, то тогда мы можем обрабатывать событие TextChanged у тех же текстовых полей.
0 / 0 / 0 Регистрация: 16.05.2016 Сообщений: 8 |
|
1 |
|
Вывести окно с ошибкой при вводе пользователем некорректного выражения16.05.2016, 06:47. Показов 14149. Ответов 1
Здравствуйте.
0 |
AndreyVorobey 2742 / 1653 / 876 Регистрация: 14.04.2015 Сообщений: 5,634 |
||||
16.05.2016, 16:07 |
2 |
|||
Сообщение было отмечено Zerroo как решение Решение
1 |
Introduction
In this example, we will see how to use the ErrorProvider control in Windows forms to provide validations in Windows Forms and display user-friendly error messages to the user if the validation fails.
Figure 1: Error Provider Sample
The complete code listing is provided at the end of the sample.
Create a new Visual C# Windows Forms application. The project will create a default form, Form1.cs. Add controls as shown in the figure below and set the properties of the controls as indicated in the table.
Figure 2: Sample Form Layout
Control | Property Name | Property Value |
Label | Text | «Setup Driving Test Appointment» |
Label | Text | «Name» |
TextBox | Text | «» |
Label | Text | «Age» |
TextBox | Text | «» |
Label | Text | «Test Date» |
DateTimePicker | Text | «Create Appointment» |
Button | Text |
Table 1: Properties for Sample Form Layout Controls
Now add an ErrorProvider control to the Form. In Visual Studio.Net, you can drag and drop the control from the toolbox. The control is added to the form and displayed in the control tray in the Windows form in Design view. If you are not using Visual Studio.Net, then you can add the control in the code. Please refer to the code listing provided at the end of the article.
Now create an event handler for the «Validating» event of the textBox1 control. We will validate the TextBox to ensure that the user has entered a value.
- private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateName();
- }
- private bool ValidateName()
- {
- bool bStatus = true;
- if (textBox1.Text == «»)
- {
- errorProvider1.SetError(textBox1, «Please enter your Name»);
- bStatus = false;
- }
- else
- errorProvider1.SetError(textBox1, «»);
- return bStatus;
- }
Code Snippet: Validate the Name TextBox
Next we will add the validations for the textBox2 control which accepts Age as the data input. We will ensure that the Age is mandatory, is in numeric format and the user is 18 years or older.
- private void textBox2_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateAge();
- }
- private bool ValidateAge()
- {
- bool bStatus = true;
- if (textBox2.Text == «»)
- {
- errorProvider1.SetError(textBox2, «Please enter your Age»);
- bStatus = false;
- }
- else
- {
- errorProvider1.SetError(textBox2, «»);
- try
- {
- int temp = int.Parse(textBox2.Text);
- errorProvider1.SetError(textBox2, «»);
- if (temp < 18)
- {
- errorProvider1.SetError(textBox2, «You must be atleast 18 years old to setup a test»);
- bStatus = false;
- }
- else
- {
- errorProvider1.SetError(textBox2, «»);
- }
- }
- catch
- {
- errorProvider1.SetError(textBox2, «Please enter your age as a number»);
- bStatus = false;
- }
- }
- return bStatus;
- }
Code Snippet: Validate the Age TextBox
Now we will add the validations for the DateTimePicker controls which collects the Test Date information. We will implement the business rule to allow test appointments to be set up on weekdays only using validation on the form.
- private void dateTimePicker1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateTestDate();
- }
- private bool ValidateTestDate()
- {
- bool bStatus = true;
- if ((dateTimePicker1.Value.DayOfWeek == DayOfWeek.Sunday) || dateTimePicker1.Value.DayOfWeek == DayOfWeek.Saturday))
- {
- errorProvider1.SetError(dateTimePicker1, «Appointment cannot be scheduled in the weekend. Please select a weekday»);
- bStatus = false;
- }
- else
- errorProvider1.SetError(dateTimePicker1, «»);
- return bStatus;
- }
Code Snippet: Validate the Date Selection
Invoking the SetError method of the ErrorProvider control displays an error indicator image next to the control specified as the first argument to the SetError method. The string specified in the second argument in the function invocation is displayed as the tooltip when the mouse is moved over the Error indicator.
When the user enters data in the controls which fail validation, a blinking error image is displayed on the form next to the control, and the error message is displayed as a tooltip to the error image.
You can display multiple error indications on a form at the same time using the same ErrorProvider control. You can also display errors that occur in DataSets. You need to set the DataSource, DataMember, and ContainerControl properties of the ErrorProvider control to set the error for a databound control. To display the dataset column error, invoke the SetColumnError method of the ErrorProvider.
You can customize the ErrorProvider control to set the BlinkRate and BlinkStyle. You can also display a custom error image instead of the default image.
Now we will add code in our sample to validate the complete form when the «Create Appointment» button is clicked.
- private void ValidateForm()
- {
- bool bValidName = ValidateName();
- bool bValidAge = ValidateAge();
- bool bValidTestDate = ValidateTestDate();
- if (bValidName && bValidAge && bValidTestDate)
- MessageBox.Show(«Appointment will be created now»);
- else
- MessageBox.Show(«Please enter valid data»);
- }
Code Snippet: Validate all form controls when the Create Appointment button is clicked
If the user clicks the Create Appointment button and the data is not valid, error indicators are displayed next to the controls with invalid data.
Validation in Action
Figure 3: Validation Form
Figure 4: Validation Errors
Figure 5: Error message displayed in addition to the form error indicators.
Complete Code Listing: Save as ValidatingForm.cs
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Data;
- namespace SampleApp
- {
- public class Form1 : System.Windows.Forms.Form
- {
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.TextBox textBox1;
- private System.Windows.Forms.TextBox textBox2;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.DateTimePicker dateTimePicker1;
- private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Button button1;
- private System.Windows.Forms.ErrorProvider errorProvider1;
- public Form1()
- {
- this.label1 = new System.Windows.Forms.Label();
- this.textBox1 = new System.Windows.Forms.TextBox();
- this.textBox2 = new System.Windows.Forms.TextBox();
- this.label2 = new System.Windows.Forms.Label();
- this.label3 = new System.Windows.Forms.Label();
- this.dateTimePicker1 = new System.Windows.Forms.DateTimePicker();
- this.label4 = new System.Windows.Forms.Label();
- this.button1 = new System.Windows.Forms.Button();
- this.errorProvider1 = new System.Windows.Forms.ErrorProvider();
- this.SuspendLayout();
- this.label1.Location = new System.Drawing.Point(8, 40);
- this.label1.Name = «label1»;
- this.label1.Size = new System.Drawing.Size(80, 16);
- this.label1.TabIndex = 0;
- this.label1.Text = «Name»;
- this.label1.Click += new System.EventHandler(this.label1_Click);
- this.textBox1.Location = new System.Drawing.Point(96, 40);
- this.textBox1.Name = «textBox1»;
- this.textBox1.Size = new System.Drawing.Size(104, 20);
- this.textBox1.TabIndex = 1;
- this.textBox1.Text = «»;
- this.textBox1.Validating += new System.ComponentModel.CancelEventHandler this.textBox1_Validating);
- this.label2.Location = new System.Drawing.Point(8, 64);
- this.label2.Name = «label2»;
- this.label2.Size = new System.Drawing.Size(80, 16);
- this.label2.TabIndex = 3;
- this.label2.Text = «Age»;
- this.textBox2.Location = new System.Drawing.Point(96, 64);
- this.textBox2.Name = «textBox2»;
- this.textBox2.Size = new System.Drawing.Size(104, 20);
- this.textBox2.TabIndex = 4;
- this.textBox2.Text = «»;
- this.textBox2.Validating += new System.ComponentModel.CancelEventHandler this.textBox2_Validating);
- this.label3.Location = new System.Drawing.Point(8, 88);
- this.label3.Name = «label3»;
- this.label3.Size = new System.Drawing.Size(80, 16);
- this.label3.TabIndex = 5;
- this.label3.Text = «Test Date»;
- this.dateTimePicker1.Location = new System.Drawing.Point(96, 88);
- this.dateTimePicker1.Name = «dateTimePicker1»;
- this.dateTimePicker1.TabIndex = 6;
- this.dateTimePicker1.Validating += new System.ComponentModel.CancelEventHandler(this.dateTimePicker1_Validating);
- this.label4.Font = new System.Drawing.Font(«Microsoft Sans Serif», 8.25F, System.Drawing.FontStyle.Bold,
- System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label4.Location = new System.Drawing.Point(16, 8);
- this.label4.Name = «label4»;
- this.label4.Size = new System.Drawing.Size(184, 23);
- this.label4.TabIndex = 7;
- this.label4.Text = «Setup Driving Test Appointment»;
- this.button1.Location = new System.Drawing.Point(80, 128);
- this.button1.Name = «button1»;
- this.button1.Size = new System.Drawing.Size(120, 23);
- this.button1.TabIndex = 8;
- this.button1.Text = «Create Appointment»;
- this.button1.Click += new System.EventHandler(this.button1_Click);
- this.errorProvider1.DataMember = null;
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(320, 173);
- this.Controls.AddRange(new System.Windows.Forms.Control[] { this.button1, this.label4, this.dateTimePicker1, this.label3, this.label2, this.textBox2, this.textBox1, this.label1 });
- this.Name = «Form1»;
- this.Text = «Form1»;
- this.Load += new System.EventHandler(this.Form1_Load);
- this.ResumeLayout(false);
- }
- [STAThread]
- static void Main()
- {
- Application.Run(new Form1());
- }
- private void label1_Click(object sender, System.EventArgs e)
- {
- }
- private void Form1_Load(object sender, System.EventArgs e)
- {
- errorProvider1.ContainerControl = this;
- }
- private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateName();
- }
- private void textBox2_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateAge();
- }
- private void dateTimePicker1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- ValidateTestDate();
- }
- private void button1_Click(object sender, System.EventArgs e)
- {
- ValidateForm();
- }
- private void ValidateForm()
- {
- bool bValidName = ValidateName();
- bool bValidAge = ValidateAge();
- bool bValidTestDate = ValidateTestDate();
- if (bValidName && bValidAge && bValidTestDate)
- MessageBox.Show(«Appointment will be created now»);
- else
- MessageBox.Show(«Please enter valid data»);
- }
- private bool ValidateName()
- {
- bool bStatus = true;
- if (textBox1.Text == «»)
- {
- errorProvider1.SetError(textBox1, «Please enter your Name»);
- bStatus = false;
- }
- else
- errorProvider1.SetError(textBox1, «»);
- return bStatus;
- }
- private bool ValidateAge()
- {
- bool bStatus = true;
- if (textBox2.Text == «»)
- {
- errorProvider1.SetError(textBox2, «Please enter your Age»);
- bStatus = false;
- }
- else
- {
- errorProvider1.SetError(textBox2, «»);
- try
- {
- int temp = int.Parse(textBox2.Text);
- errorProvider1.SetError(textBox2, «»);
- if (temp < 18)
- {
- errorProvider1.SetError(textBox2, «You must be atleast 18 years old to setup a test»);
- bStatus = false;
- }
- else
- {
- errorProvider1.SetError(textBox2, «»);
- }
- }
- catch
- {
- errorProvider1.SetError(textBox2, «Please enter your age as a number»);
- bStatus = false;
- }
- }
- return bStatus;
- }
- private bool ValidateTestDate()
- {
- bool bStatus = true;
- if ((dateTimePicker1.Value.DayOfWeek == DayOfWeek.Sunday) ||
- (dateTimePicker1.Value.DayOfWeek == DayOfWeek.Saturday))
- {
- errorProvider1.SetError(dateTimePicker1, «Appointment cannot be scheduled in the weekend. Please select a weekday»);
- bStatus = false;
- }
- else
- errorProvider1.SetError(dateTimePicker1, «»);
- return bStatus;
- }
- }
- }
NOTE: This article is purely for demonstration. This article should not be construed as the best practices white paper. This article is entirely original, unless specified. Any resemblance to other material is an un-intentional coincidence and should not be misconstrued as malicious, slanderous, or any anything else hereof.
Conclusion
In this example, we learned how to invoke validate input to Windows Forms controls and display user-friendly informative error messages.