2012年5月26日土曜日

NUnitをインストール

今までVisual C# 2010 Expressを使用していて単体テストツールは入っていませんでした。 「ちょっとは触っておいた方がいいかなぁ」と思ったので試しにVisual Studioで外部ツールとして使えるNUnitを入れてみました。

環境は、

  • Windows 7 home 64bit
  • Visual C# 2010 Express
  • NUnit 2.6.0.12051

まずはNUnitをオフィシャルサイトから落としてきて普通にインストール。 次に、Visual Studioのツールメニューから「外部ツール」をクリック。 NUnitを登録します。 取りあえずx86版だけ使えればいいのでこんな感じで登録。

  • タイトル : NUnit(x86)
  • コマンド : インストール先フォルダ\NUnit 2.6\bin\nunit-x86.exe
  • 引数 : /run $(ProjectDir)$(ProjectFileName)
  • 初期ディレクトリ ; $(ProjectDir)

2012年5月22日火曜日

wpf : TemplateからNameを元にコントロールを探す

ちょっとした覚書。 TemplateからNameを元にコントロールを探すにはControlTemplate.FindNameメソッドまたはFrameworkElement.GetTemplateChildメソッドを使うようです。 FrameworkElement.FindNameメソッドはTemplateの中までは探してくれないらしい。 参考サイトはこちら。

1つのTemplateが複数のコントロールに適用された場合、同じNameのコントロールがその数だけ作成されます。 なのでNameでコントロールを探すときはVisualTreeHelperを使うのではなく、名前スコープを考慮したこれらのメソッドを使うものなんだそうです。 気付くのに遅れて無駄足を踏んでしまった...

メソッドということでxamlからは使用できません。

2012年5月19日土曜日

wpf : AdornerにAssertを埋め込んだらVisual Studioごと落ちた

Adornerを継承したクラスを作りました。

public class TabMoveCursor : Adorner
{
    protected override int VisualChildrenCount
    {get{return _cursorCanvas == null ? 0 : 1;}}
    
    protected override Visual GetVisualChild(int index)
    {
        if (_cursorCanvas == null)
            throw new IndexOutOfRangeException("子要素はない");
        if (index != 0)
            throw new IndexOutOfRangeException("子要素は1つのみ");
        return _cursorCanvas;
    }

    ~色々略~

    private Canvas _cursorCanvas = null;

    protected override Size ArrangeOverride(Size finalSize)
    {
        Debug.Assert(_cursorCanvas != null);
        _cursorCanvas.Arrange(new Rect());

        return finalSize;
    }
}

2012年5月15日火曜日

wpf : リソースをC#で読み込んでxamlで使う

ちょっと前にカスタムコントロール.Resourcesが使えないという状況を発見したので、リソースをC#で読み込んでxamlで使う方法について調べてみました。 カスタムコントロール.Resourcesが使えない状況というのはこちらのネタでのお話です。

普通にやってたら気にしなくてもいいような内容ですね。 まぁ、カスタムコントロールの方は置いとくとして、リソースの読み込み方は他に役に立つこともあるかもしれないので投稿します。

xamlでResourcesプロパティに書くことができるリソースは、

  • FrameworkElement.Resources ... イミディエイト リソース
  • Application.Resources ... アプリケーション リソース

と呼ぶのだそうです。

2012年5月8日火曜日

wpf : ItemsControl系のカスタムコントロールでStyleを使わずにコンテナ作成を検出

ItemsControl系のカスタムコントロールにイベントを登録するため、コンテナ作成を検出する方法を調べてみました。 ItemsControlというのはListBox、TabControl、TreeViewなどです。 コンテナというのはそれぞれの項目を表示するための、???Itemという名前が付いたコントロール(ListBoxItem、TabItem、TreeViewItemなど)です。 wpfではItemsControlに様々な型のコンテンツを登録できます。 例えばListBoxに対して、

listBox.ItemsSource = new ObservableCollection<string>()
{
    "文字列1",
    "文字列2",
    "文字列3"
};

という風に文字列のコンテンツを登録できます。 その場合、登録したコンテンツは当然GUIコントロールではありません。 コンテンツを表示するためのコントロールが別に必要になります。 それがコンテナ(ItemContainer)です。

2012年5月3日木曜日

wpf : TabItemのヘッダにClickイベントを登録

前の投稿の続きです。 前の投稿では「TabItemのヘッダで使えるマウスイベントはPreviewが付くトンネルイベントだけ」ということを書きました。 それだけ使えれば十分だとは思いますが、今回はなぜか、TabItemのヘッダにClickイベントを登録する方法を試してみました。

やり方は簡単で、TabItemのTemplateにButtonを登録するだけです。 ヘッダーに関するTemplateはTabItem.Template(ControlTemplate)とTabItem.HeaderTemplate(DataTemplate)の2種類あります。 TabItem.Templateの方には枠線などタブの外観を設定します。 TabItem.HeaderTemplateは、DataTemplate型とあるとおり、関連付けられたデータのGUI表現を設定します。 例えば「アイコンとテキストで表現するデータ」があった場合、それをどういう構成にするかの設定がDataTemplateです。 まず、タブの外観がTabItem.Templateを元に作られ、その中にHeaderTemplateを元に作ったデータが収められます。 わざわざ2つに分かれているのは、DataTemplateをメニューやリストボックスなど様々なコントロールで共有できるようにするためでしょう。

2012年5月2日水曜日

wpf : TabItemのヘッダにマウスイベントを登録

TabItemのヘッダにマウスイベントを登録する場合について考えます。 xamlで全部のTabItemにイベントを書く場合には特に考える必要はありません。 普通にこんなふうに書きます。

<TabItem
        Header="ささ"
        PreviewMouseLeftButtonDown="OnPreviewMouseLeftButtonDown"
>
    パンダ
</TabItem>

でも、全部のTabItemに同じイベントを登録するときはイチイチ書くのは面倒ですよね? そして、ItemsSourceを使う場合はイベントを直書きすることもできません。 こういう場合はItemContainerStyleでイベントを登録します。

このItemContainerStyleの「ItemContainer」というのはTabItemのことです。 「TabControlに登録された各項目(Item)をTabControl上で表示するためのコンテナ」のことを表しています。 TabControlに限らず、ItemsControl系のコントロールにはこの様なItemContainerが用意されています。 ListBoxならListBoxItem、TreeViewにはTreeViewItemといった具合です。