I'm pretty new to C#, and I'm quite stuck on the following problem.
I would like to add to my application a Windows.Form (singleton) on
which I could display a message of one of the following type :
Exception, Error, Warning, Infos (with differents colors, etc).
I would like to use it like the Console.WriteLine("My Message"); on
everywhere in my application.
Something like that :
Expand|Select|Wrap|Line Numbers
- using MyApp.Tools;
- //popup (if not already displayed) and display the error
- LogViewer.WriteLine(MessageType.Error, "Something bad happenend");
I already tried many things but I always have problems ("Windows Handle
Already Exists", form not refreshing (aka no messages loop), form not
displaying, etc.)
Sorry but I'm out of ideas. So if any one is ready to give me a very
useful help it would be really appreciated !
Here is my test class, lot's of things are commented because I made a
lot's of test.
Main questions and remarks are :
- Is the delegate way of doing ok ?
- Since this code can be called before the main Application.Run(new
MainForm) should I call an Application.Run() for this form ?
- How to cleanly prevent the component of the form not to be released
when closing the form
Ok here we go :
using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
namespace Tools
{
/// <summary>
/// A singleton to display message in a windows form
/// </summary>
public class LogViewer : System.Windows.Forms.Form
{
//a delegate to update the rich text box from everywhere (another
thread)
private delegate void UpdateLogRtb(MessageType _Type, string _Text);
public enum MessageType
{
Info,
Error,
Exception
}
/// <summary>
/// Required designer variable.
/// </summary>
///
//common to all instances
private static bool m_IsDisplayed;
static private int m_CurrentLine;
private static System.Windows.Forms.RichTextBox richTextBox = new
RichTextBox();
private static System.Windows.Forms.Button btnSaveAs = new
System.Windows.Forms.Button();
private static System.Windows.Forms.Button btnClearLog = new
System.Windows.Forms.Button();
private static System.Threading.Thread m_UiThread;
static private LogViewer m_LogViewer = new LogViewer();
static LogViewer()
{
InitializeComponent();
m_IsDisplayed = false;
m_CurrentLine = 0;
}
/// <summary>
/// Private constructor, singleton
/// </summary>
private LogViewer()
{
//new thread ready to start
//m_UiThread = new System.Threading.Thread(new
System.Threading.ThreadStart(UIThread));
//m_UiThread.Start();
}
//private void UIThread()
//{
// Application.Run(Instance);
//}
public static LogViewer Instance
{
get
{
return m_LogViewer;
}
}
public static void UpdateLog(MessageType _Type, string _Text)
{
if ( Instance.InvokeRequired )
{
UpdateLogRtb delUpdate = new UpdateLogRtb(UpdateLog);
Instance.BeginInvoke(delUpdate, new object[]{_Type, _Text});
}
else
{
lock(richTextBox)
{
if(!m_IsDisplayed)
{
Instance.Show();
m_IsDisplayed = true;
}
Instance.SetColor(_Type);
richTextBox.AppendText(_Text);
}
}
}
void SetColor(MessageType _Type)
{
switch(_Type)
{
case MessageType.Error : richTextBox.SelectionColor =
System.Drawing.Color.Fuchsia;
break;
case MessageType.Exception : richTextBox.SelectionColor =
System.Drawing.Color.Red;
break;
case MessageType.Info : richTextBox.SelectionColor =
System.Drawing.Color.Blue;
break;
}
}
public static void WriteLine(MessageType _Type ,string _Text,
object[] _Parameters)
{
IEnumerator iter = _Parameters.GetEnumerator();
Write(_Type, "[" + DateTime.Now.ToShortDateString() + " " +
DateTime.Now.ToLongTimeString() + "] "+ _Text + " ");
while(iter.MoveNext())
{
Write(_Type, iter.Current.ToString());
Write(_Type, " ");
}
Write(_Type, "\n");
}
public static void WriteLine(MessageType _Type ,string _Text, object
_Parameter)
{
Write(_Type, "[" + DateTime.Now.ToShortDateString() + " " +
DateTime.Now.ToLongTimeString() + "] "+ _Text + " ");
Write(_Type, _Parameter.ToString());
Write(_Type,"\n");
}
public static void WriteLine(MessageType _Type, string _Text)
{
Write(_Type, "[" + DateTime.Now.ToShortDateString() + " " +
DateTime.Now.ToLongTimeString() + "] "+ _Text + " ");
Write(_Type,"\n");
m_CurrentLine++;
}
public static void Write(MessageType _Type, string _Text)
{
UpdateLog(_Type, _Text);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
m_IsDisplayed = false;
}
#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 static void InitializeComponent()
{
Instance.SuspendLayout();
//
// richTextBox
//
richTextBox.Cursor = System.Windows.Forms.Cursors.Arrow;
richTextBox.Location = new System.Drawing.Point(0, 0);
richTextBox.Name = "richTextBox";
richTextBox.ReadOnly = true;
richTextBox.Size = new System.Drawing.Size(640, 250 );
richTextBox.TabIndex = 0;
richTextBox.Text = "";
richTextBox.WordWrap = false;
//
// btnSaveAs
//
btnSaveAs.Location = new System.Drawing.Point(446, 254);
btnSaveAs.Name = "btnSaveAs";
btnSaveAs.Size = new System.Drawing.Size(89, 23);
btnSaveAs.TabIndex = 1;
btnSaveAs.Text = "Save as...";
btnSaveAs.Click += new System.EventHandler(btnSaveAs_Click);
//
// btnClearLog
//
btnClearLog.Location = new System.Drawing.Point(538, 254);
btnClearLog.Name = "btnClearLog";
btnClearLog.Size = new System.Drawing.Size(100, 23);
btnClearLog.TabIndex = 2;
btnClearLog.Text = "Clear Log";
btnClearLog.Click += new System.EventHandler(btnClearLog_Click);
//
// LogViewer
//
//m_LogViewer.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
Instance.ClientSize = new System.Drawing.Size(640, 280);
Instance.Controls.Add(btnClearLog);
Instance.Controls.Add(btnSaveAs);
Instance.Controls.Add(richTextBox);
Instance.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.FixedToolWind ow;
Instance.Name = "LogViewer";
Instance.Text = "Events viewer";
Instance.Closing += new
System.ComponentModel.CancelEventHandler(LogViewer _Closing);
Instance.ResumeLayout(false);
}
#endregion
private static void LogViewer_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
Instance.Hide();
}
private static void btnSaveAs_Click(object sender, System.EventArgs
e)
{
SaveFileDialog saveFile = new SaveFileDialog();
saveFile.FileName = "QueueMeEvents.log";
if (saveFile.ShowDialog() != DialogResult.Cancel)
{
StreamWriter mySaveFile = File.CreateText(@saveFile.FileName);
mySaveFile.AutoFlush = true;
mySaveFile.Write(richTextBox.Text);
mySaveFile.Close();
}
}
private static void btnClearLog_Click(object sender, System.EventArgs
e)
{
richTextBox.Clear();
m_CurrentLine = 0;
}
// protected override void OnPaint(PaintEventArgs e)
// {
// base.OnPaint (e);
// Application.DoEvents();
// Invalidate();
// System.Threading.Thread.Sleep(100);
// }
}
}
Thanks !