TreeView 全体で表示されるコンテキストメニューは そのまま ContextMenu プロパティに設定すればいい。
<TreeView>
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="ユーザー追加" Click="mnuAddUser_Click"/>
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
TreeView の各アイテム TreeViewItem のコンテキストメニューはまず TreeView の ItemContainerStyle に スタイルを設定してやる。
<TreeView ItemContainerStyle="{StaticResource treeViewTopLevelStyle}">
treeViewTopLevelStyle はこのあと定義する Style の x:Key である。
次に Window.Resources などにコンテキストメニューとスタイルを定義する。
<ContextMenu x:Key="topLevelTreeMenu">
<MenuItem Header="追加" Click="mnuAddPlan_Click" />
<MenuItem Header="削除" Click="mnuRemoveUser_Click"/>
</ContextMenu>
<Style x:Key="treeViewTopLevelStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource topLevelTreeMenu}" />
<EventSetter Event="TreeViewItem.MouseRightButtonDown" Handler="TreeViewItem_MouseRightButtonDown"/>
</Style>
ContextMenu は特に難しくない。x:Key を設定しておく。
Style では、まず <Setter Property="ContextMenu"> で先の ContextMenu をコンテキストメニューに設定している。 注意が必要なのは次の <EventSetter Event="TreeViewItem.MouseRightButtonDown"> である。 これは アイテムの上で右クリックしたときにその項目が選択されないので、それを回避するためである。
また、ソース側に次のようにイベントハンドラを書く。
private void TreeViewItem_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is TreeViewItem)
{
var item = sender as TreeViewItem;
item.IsSelected = true;
e.Handled = true;
}
}
これで、右クリックされたアイテムを選択状態にできる。 この動作が適切かどうかはソフトによると思うが、少なくとも表示上はこちらのほうが親切に見える。
あともう一つ、注意点として、<Setter Property="ContextMenu"> で <Setter.Value> として、直接 ContextMenu を定義してもよさそうだが、これはうまくいかない。
'connectionId の設定時に例外がスローされました。' 行番号 'xx'、行位置 'xx'。
などと XamlParseException が発生して怒られる。
たぶん Click イベントの関連づけができないのだと思うが、ContextMenu を上のように分けて x:Key で関連づけている限りは怒られないので、これでよしとする。
Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。
好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。
詳しくは Web mixi で。