2010年09月01日

MenuItemとHierarchicalDataTemplate /WPF

前々回の続き。今回のテーマは、階層メニューです。前回でなく前々回なのは、今回は前回扱った動静混在メニューは置いておくからです。題材は引き続きブラウザのブックマーク。

この記事では、実際に URL を持っていてクリックすればそのページに飛べるのをブックマーク、複数のブックマークを子要素に持てるのをフォルダと呼ぶことにします。フォルダは子要素にブックマークの他にさらにフォルダを持つことも可能とします。

まずこういうもののクラス構造を考えましょう。フォルダの下にフォルダとブックマークが混在可能なのですから、一つのコレクションで扱うために共通の基底クラスが欲しいところです。表示名 Title は共通要素ですね。ブックマークは子要素を持たない代わりに URL を保持します。となるとまずこんな感じでしょう。

// Bookmark.cs
public abstract class BookmarkBase {vw
    public string Title { get; set; }
}
public class Bookmark : BookmarkBase {
    public string Url { get; set; }
    public Bookmark() { }
    public Bookmark(string title, string url) {
        this.Title = title;
        this.Url = url;
    }
}
public class BookmarkFolder : BookmarkBase {
    public ICollection<BookmarkBase> Items { get; private set; }
    public BookmarkFolder() {
        this.Items = new ObservableCollection<BookmarkBase>();
    }
    public BookmarkFolder(string title, params BookmarkBase[] items) {
        this.Title = title;
        this.Items = new ObservableCollection<BookmarkBase>(items);
    }
}

このクラスを使って、Windows1 の DataContext に設定します。

// App.xaml.cs
private void App_Startup(object sender, StartupEventArgs e) {
    Window1 window = new Window1();
    ObservableCollection<BookmarkBase> bookmarks =
        new ObservableCollection<BookmarkBase>();
    bookmarks.Add(new BookmarkFolder("検索エンジン", 
        new Bookmark("bing", "http://www.bing.com"),
        new BookmarkFolder("google",
            new Bookmark("google.co.jp", "http://www.google.co.jp"),
            new Bookmark("google.com", "http://www.google.com")),
        new BookmarkFolder("yahoo",
            new Bookmark("yahoo", "http://www.yahoo.co.jp"))));
    bookmarks.Add(new Bookmark("msdn", "http://msdn.microsoft.com"));
    window.DataContext = bookmarks;
    window.Show();
}

あとは XAML です。基本的に前々回の XAML と同じですが、ツリー状のデータをバインディングで展開するために、DisplayMemberPath だけで済ませる訳にはいきません。ItemTemplate で HierarchicalDataTemplate を使って繰り返しを表現します。

<!-- Window1.xaml -->
<!-- MenuItem の書き換え部分だけ抜粋 -->
<MenuItem Header="ブックマーク(_B)" ItemsSource="{Binding}">
  <MenuItem.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Items}">
      <TextBlock Text="{Binding Title}"/>
    </HierarchicalDataTemplate>
  </MenuItem.ItemTemplate>
  <!-- 以下は元のまま -->

まあ DisplayMemberPath の代わりに ItemTemplate 書いただけで終わりなんですが。割と見たままなんで解説もいいですよね。

posted by Hongliang at 17:57| Comment(0) | TrackBack(0) | WPF | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。