PropertyGridにコピペ機能を追加する(２/2) - LINQPad連携

#はじめに
前回はPropertyGridのアイテムをテキストでコピーしました。
今回はLINQPadと連携してhtmlビューを作成したいと思います。
[第1回はこちら http://qiita.com/longlongago_k/items/70969b2af04af58ae70d](http://qiita.com/longlongago_k/items/70969b2af04af58ae70d)
![Figure5.png](https://qiita-image-store.s3.amazonaws.com/0/98713/a78f5bf1-c123-a2c5-6ff7-c74f8f8532f1.png)

大まかな実装の流れは下記のとおりです。所要時間は15分です。
1. 簡易HTMLビューアを作成
2. LINQPadを使用したhtml出力コマンドの作成

#簡易HTMLビューアの作成
出力したHTMLは保存してもよいのですが、パパッと値を見るためには内臓のhtmlビューアに表示したほうが便利です。
WebBrowserコントロールを張り付けるだけの簡単なhtmlビューアを作ってみましょう。

まず、前回のプロジェクトに新しいフォームHTMLView.cs追加します。フォームにWebBrowser、SaveFileDialog、保存ボタンを追加します。
![Figure6.png](https://qiita-image-store.s3.amazonaws.com/0/98713/5e532a85-53e5-b22c-bed5-3cbed84f35c1.png)

コードは下記のとおりです。コンストラクタでhtmlソースを渡して表示できるようにしたのと、htmlファイルの保存機能を追加しただけです。

```csharp
  public partial class HtmlView : Form
  {
    public HtmlView()
    {
      InitializeComponent();
    }

    public HtmlView(string htmlSourceText) : this()
    {
      SetSourceHtml(htmlSourceText);
    }

    public void SetSourceHtml(string htmlSourceText)
    {
      webBrowser.DocumentText = htmlSourceText;
    }

    private void buttonSaveAs_Click(object sender, EventArgs e)
    {
      try
      {
        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
        {
          using (StreamWriter sw = new StreamWriter(saveFileDialog1.FileName, false, Encoding.UTF8))
            sw.Write(webBrowser.DocumentText);
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.ToString(), "error");
      }

    }
  }
```
##LINQPad連携HTML出力
LINQPadとは、通常単独で使用する便利ツールなのですが、アセンブリとしてプログラムに直接組み込むことでLINQPadの便利機能を使用することができます。

まずは、プロジェクトにLINQPadフォルダを作成し、LINQPad.exeをコピーします。
次に、参照の追加→コピーしてきたLINQPad.exeを選択します。（※）

※ わざわざLINQPadをプロジェクトにコピーせずとも、インストールしたLINQPad.exeを直接参照してもOKです。
![Figure7.png](https://qiita-image-store.s3.amazonaws.com/0/98713/ad0ad623-883c-bf42-354a-b45a86f08c96.png)

次に、コンテクストメニューにHTML出力のメニューを作成し、Clickイベントに下記コードを追加します。

```csharp
    private void ToolStripMenuItemCopyToHtml_Click(object sender, EventArgs e)
    {
      try
      {
        object val;
        if (SelectedGridItem.GridItemType == GridItemType.Category)
        {
          val = SelectedGridItem.GridItems.Cast<GridItem>().Select(x => new { x.Label, x.Value });
        }
        else
        {
          val = SelectedGridItem.Value;
        }
        string text = LINQPad.Util.ToHtmlString(true, 10, val);
        Clipboard.SetText(text);
        HtmlView hv = new HtmlView();
        hv.SetSourceHtml(text);
        hv.Show();
      }
      catch (System.IO.FileNotFoundException ex)
      {
        MessageBox.Show("LINQPad.exeが見つかりませんでした。\r\n" + ex.ToString(), "error");
      }
    }
```

コードの内容は大体以下のような感じです。
1.  LINQPad.Util.ToHtmlString()でHTMLソースの取得
2.  htmlViewにhtmlソースを渡してFormをShowする。

ここで、気を付けないといけないのは、PropertyGridのカテゴリ名も選択できてしまうということです。
カテゴリを選択したときは、子要素を以下のように取得する必要があります。Cast関数はLINQのSelectを呼び出すのに必要な処理です。forで書く場合はたぶん必要ありません。

```csharp
val = SelectedGridItem.GridItems.Cast<GridItem>().Select(x => new { x.Label, x.Value });
```

非常に簡単ですが、以上です。シンプルで便利なのでぜひ試してみてください。
ここまでのプロジェクトを以下に置いておきます。 右クリックから保存してjpg→zipにリネームしてください。
![PropertyGridPlus_html.zip.jpg](https://qiita-image-store.s3.amazonaws.com/0/98713/16819859-6248-cbd0-9390-52f2311c9645.jpeg)

追記
今回の方法だと、自作アプリのexeと同じ場所にLINQPad.exeが配置されます。
サブフォルダに配置する方法もありますが説明を割愛しています。