// Исходный код компонента:
namespace ControlsLogger
{
public partial class ControlsLogger : Component, ISupportInitialize
{
private Form _hostingForm;
public static Action<string> Log { get; set; }
private readonly List<Control> _controls = new List<Control>();
// this hack is used to get component's hosting (parent) form
// http://www.informit.com/articles/article.aspx?p=169528&seqNum=2 has an explanation of this hack.
// if the site above is not available, search the code below in google
[BrowsableAttribute(false)]
public Form HostingForm
{
// Used to populate InitializeComponent at design time
get
{
if ((_hostingForm == null) && DesignMode)
{
// Access designer host and obtain reference to root component
var designer = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designer != null)
_hostingForm = designer.RootComponent as Form;
}
return _hostingForm;
}
set { _hostingForm = value; }
}
public ControlsLogger()
{
InitializeComponent();
}
public ControlsLogger(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void BeginInit()
{
// do nothing
}
public void EndInit()
{
// we access parent form from this method, because in constructor we don't have
// a reference to the parent form, and the parent form doesn't have controls added yet.
if (_hostingForm == null) return;
foreach (Control control in _hostingForm.Controls)
{
AddChildControls(control);
}
SubscribeToControls();
}
private void SubscribeToControls()
{
_hostingForm.Closed += Form_Closed;
_hostingForm.Activated += Form_Activated;
foreach (Control control in _controls)
{
if (control is Button)
{
control.Click += Control_Click;
}
else if (control is MenuStrip)
{
MenuStripHelper menuStripHelper = new MenuStripHelper();
foreach (ToolStripMenuItem menuItem in menuStripHelper.GetAllMenuItems((MenuStrip)control))
{
menuItem.Click += MenuItem_Click;
}
}
else if (control is ComboBox)
{
((ComboBox)control).SelectedIndexChanged += ComboBox_SelectedIndexChanged;
}
else if (control is CheckBox)
{
((CheckBox)control).CheckedChanged += CheckBox_CheckedChanged;
}
}
}
private void AddChildControls(Control parentControl)
{
_controls.Add(parentControl);
foreach (Control childControl in parentControl.Controls)
{
AddChildControls(childControl);
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox == null || Log == null) return;
Log(string.Format("ComboBox '{0}', selected item changed: '{1}'", comboBox.Name, comboBox.Text));
}
private void Form_Activated(object sender, EventArgs e)
{
Form form = sender as Form;
if (form == null || Log == null) return;
Log(string.Format("Form '{0}' activated", form.Text));
}
private void Form_Closed(object sender, EventArgs e)
{
Form form = sender as Form;
if (form == null || Log == null) return;
Log(string.Format("Form '{0}' closed", form.Text));
}
private void Control_Click(object sender, EventArgs e)
{
Control control = sender as Control;
if(control == null || Log == null) return;
Log(string.Format("{0} '{1}' pressed", control.GetType().Name, control.Text));
}
private void MenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem control = sender as ToolStripMenuItem;
if (control == null || Log == null) return;
Log(string.Format("Menu Item '{0}' pressed", control.Text));
}
private void CheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox control = sender as CheckBox;
if (control == null || Log == null) return;
Log(string.Format("CheckBox '{0}' new checked state: {1}", control.Text, control.Checked));
}
}
}
namespace ControlsLogger
{
public class MenuStripHelper
{
private readonly IList<ToolStripMenuItem> _menuItems = new List<ToolStripMenuItem>();
public IList<ToolStripMenuItem> GetAllMenuItems(MenuStrip menuStrip)
{
foreach (ToolStripMenuItem menuItem in menuStrip.Items)
{
AddSubMenus(menuItem);
}
return _menuItems;
}
public void AddSubMenus(ToolStripMenuItem menuItem)
{
_menuItems.Add(menuItem);
foreach (var submenuItem in menuItem.DropDownItems)
{
if (submenuItem is ToolStripMenuItem)
AddSubMenus((ToolStripMenuItem)submenuItem);
}
}
}
}
// Класс Log у меня использует log4net и выглядит так:
public class Log
{
private static volatile ILog _log;
private static object locker = new object();
private static ILog GetInstance()
{
if (_log == null)
{
lock (locker)
{
if (_log == null)
{
_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
var appender = new log4net.Appender.RollingFileAppender();
appender.AppendToFile = true;
appender.File = string.Format("{0}\\full-log.txt", Config.GetInstance().LogsDirectory);
appender.MaximumFileSize = "1MB";
appender.MaxSizeRollBackups = 10;
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Size;
appender.Threshold = log4net.Core.Level.All;
appender.Layout = new log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss} %message %n");
appender.ActivateOptions();
var bufferAppender = new log4net.Appender.BufferingForwardingAppender();
bufferAppender.BufferSize = 10;
bufferAppender.AddAppender(appender);
bufferAppender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(bufferAppender);
}
}
}
return _log;
}
public static void Info(string logMessage)
{
GetInstance().Info(logMessage);
}
}