Silverlight 4 Tools の日本語版がようやく公開されたので、前から気になっていた Silverliht Tools の ContextMenu を試してみた。
使い方は WPF の ContextMenu とたいして変わらない。メニューをクリックしたときに実行する処理を Click イベントハンドラか Command で指定できるところも同じ。
MainPage.xaml
<UserControl x:Class="ContextMenuSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:cinput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <StackPanel x:Name="LayoutRoot" Background="White"> <!--Clickイベントを使ったサンプル--> <TextBox x:Name="eventTextBox" Margin="20"> <cinput:ContextMenuService.ContextMenu> <cinput:ContextMenu> <cinput:MenuItem Header="コピー" Click="CopyMenuClick"/> <cinput:MenuItem Header="貼り付け" Click="PasteMenuClick"/> <cinput:MenuItem Header="切り取り" Click="CutMenuClick"/> </cinput:ContextMenu> </cinput:ContextMenuService.ContextMenu> </TextBox> <!--Commandを使ったサンプル--> <TextBox x:Name="commandTextBox" Margin="20"> <cinput:ContextMenuService.ContextMenu> <cinput:ContextMenu> <cinput:MenuItem Header="コピー" Command="{Binding Path=CopyCommand}"/> <cinput:MenuItem Header="貼り付け" Command="{Binding Path=PasteCommand}"/> <cinput:MenuItem Header="切り取り" Command="{Binding Path=CutCommand}"/> </cinput:ContextMenu> </cinput:ContextMenuService.ContextMenu> </TextBox> </StackPanel> </UserControl>
MainPage.xaml.cs
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace ContextMenuSample { public class DelegateCommand : ICommand { private Action<object> execute; private Func<object, bool> canExecute; public DelegateCommand(Action<object> execute) : this(execute, _ => true) { } public DelegateCommand(Action<object> execute, Func<object, bool> canExecute) { this.execute = execute; this.canExecute = canExecute; } public bool CanExecute(object p) { return this.canExecute(p); } public void Execute(object p) { this.execute(p); } // とりあえず実装しただけ public event EventHandler CanExecuteChanged; } public partial class MainPage : UserControl { private string eventText; private string commandText; public ICommand CopyCommand { get; private set; } public ICommand CutCommand { get; private set; } public ICommand PasteCommand { get; private set; } public MainPage() { InitializeComponent(); this.CopyCommand = new DelegateCommand(CopyCommandExecute); this.CutCommand = new DelegateCommand(CutCommandExecute); this.PasteCommand = new DelegateCommand(PasteCommandExecute); this.DataContext=this; } private void CopyMenuClick(object sender, RoutedEventArgs e) { this.eventText = this.eventTextBox.Text; } private void PasteMenuClick(object sender, RoutedEventArgs e) { if (this.eventText != null) this.eventTextBox.Text = eventText; } private void CutMenuClick(object sender, RoutedEventArgs e) { this.eventText = this.eventTextBox.Text; this.eventTextBox.Text = ""; } private void CopyCommandExecute(object p) { this.commandText = this.commandTextBox.Text; } private void CutCommandExecute(object p) { this.commandText = this.commandTextBox.Text; this.commandTextBox.Text = ""; } private void PasteCommandExecute(object p) { if(this.commandText!=null) this.commandTextBox.Text = this.commandText; } } }
実行画面
ContextMenu は右クリックで表示できるけど、テキストの選択状態が解除されてしまう。まだ編集機能には使えそうにない。
ToolBar や MenuBar のような、ドロップダウンメニューを表示するコントロールを自作するのがだいぶ楽になると思う。Silverlight に標準で含まれているのが一番いいんだけど、ね。