読者です 読者をやめる 読者になる 読者になる

Debugger Visualizerを自作する(値の書き換え)

C#

Debugger Visualizerは、ただ表示するだけではなく、値の編集も行うことが出来ます。今回は、System.Text.StringBuilderの保持する文字列の表示・編集が可能なDebugger Visualizerの作成の方法の紹介です。ちなみにStringBuilderはSerializableです。

以下はイメージ図です。Debugger Visualizerを起動すると、StringBuilderの保持する文字列がTextBoxに表示されます。それを編集すると、StringBuilderの値が書き換わります。

表示部分を作成

毎度おなじみのDebugger Visualizerの本体部分。今回はFormの定義は割愛します。

public class StringBuilderDebuggerVisualizer : DialogDebuggerVisualizer
{
    protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
    {
        StringBuilder sb = (StringBuilder)objectProvider.GetObject();

        using (StringBuilderDebuggerVisualizerDialog dialog = new StringBuilderDebuggerVisualizerDialog())
        {
            dialog.textBox1.Text = sb.ToString();
            dialog.ShowDialog();

            if (dialog.DialogResult == DialogResult.OK)
            {
                // ここに値の書き換えのコードを書く 
            }       
        }
    }
}

値の書き換え

ReplaceObjectメソッドに新しいインスタンスを指定すれば、その値に書き換わります。

if (objectProvider.IsObjectReplaceable)
{
    objectProvider.ReplaceObject(new StringBuilder(dialog.textBox1.Text));
}

ReplaceObjectに渡すオブジェクトは、StringBuilderのようなSerializableなクラスならば迷うことなく新しいインスタンスを指定すればいいのですが、SerializableではないクラスでProxyクラスを使ってやり取りしている場合は、単純にこの方法を使うとエラーになります。この回避策はまた後日に。

まとめ

public class StringBuilderDebuggerVisualizer : DialogDebuggerVisualizer
{
    protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
    {
        StringBuilder sb = (StringBuilder)objectProvider.GetObject();

        using (StringBuilderDebuggerVisualizerDialog dialog = new StringBuilderDebuggerVisualizerDialog())
        {
            dialog.textBox1.Text = sb.ToString();
            dialog.ShowDialog();

            if (dialog.DialogResult == DialogResult.OK)
            {
                if (objectProvider.IsObjectReplaceable)
                {
                    objectProvider.ReplaceObject(new StringBuilder(dialog.textBox1.Text));
                }                    
            }
        }
    }
}