1

ユーザーがクリックする WinForms ボタンのクリックごとにログ ステートメントを追加することを検討しています。理想的には、親フォームの識別子 (タイトル バーなど) を追加することです。すべてのマウス クリックをログに記録する投稿を見たことがありますが、ボタンのクリックだけをログに記録することに興味があります。ここで受け入れられた回答を読み、それを適応させました:

public class ButtonLogger
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(ButtonLogger));
    public static void AttachButtonLogging(Control.ControlCollection controls)
    {
        foreach (var button in controls.OfType<Button>())
        {
            button.Click += LogButtonClick;
        }
    }
    private static void LogButtonClick(object sender, EventArgs eventArgs)
    {
        Button button = sender as Button;
        Logger.InfoFormat("Button clicked: {0} ({1})", button.Text, button.Parent.Text);
    }
}

このクラスは、次のようなフォームのコンストラクターの最後で使用されます。

ButtonLogger.AttachButtonLogging(this.Controls);

これに直面している問題は、Controls プロパティがボタンへの参照を持っていないように見えることです。これはおそらく、ボタンがフォームに直接追加されたのではなく、Controls プロパティに別のコントロールが追加されたためです。ただし、Controls プロパティには、ToolStrip という 1 つのコントロールしか含まれていません。

親コンテナに関係なく、フォーム上のすべてのボタンを利用する方法はありますか? 私の最終的な目標は、ボタンにログ ステートメントを追加することです。これがボタン クリック イベント メソッド以外の方法で達成できる場合は、それも受け入れます。

4

2 に答える 2

4

ボタンを再帰的に検索する必要があると思います:

public static void AttachButtonLogging(Control.ControlCollection controls)
{
    foreach (var control in controls.Cast<Control>())
    {
        if (control is Button)
        {
           Button button = (Button)control;
           button.Click += LogButtonClick;
        }
        else
        {
            AttachButtonLogging(control.Controls);
        }
    }
}
于 2013-07-30T14:13:45.917 に答える
0

考えられることの 1 つは、標準Buttonクラスのサブクラスを作成し、ボタン自体にログを記録させることです。もちろん、アプリケーション内のすべてのボタンを独自の実装に置き換える必要がありますが、グローバルな検索と置換でそれを行うことができるはずです。

実装例を次に示します。

public class LoggerButton : Button
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(LoggerButton));

    protected override void OnClick(EventArgs e)
    {
        base.OnClick(e);
        Logger.InfoFormat("Button clicked: {0} ({1})", this.Text, this.Parent.Text);
    }
}
于 2013-07-30T14:22:44.613 に答える