はじめに
先日 DataBinding を使ってウィンドウにデータを表示したので、今回は Command を使ってボタンを押した時のアクションを追加してみます。
RoutedCommand を使う
public partial class EditDialog : Window { // ファイル選択ダイアログを表示するコマンド public static readonly ICommand ReferenceCommand = new RoutedCommand("ReferenceCommand", typeof(Button)); public EditDialog() { InitializeComponent(); // パスは適当 var item = new Item() { Title = "Firefox", FileName = @"C:\Program Files\Mozilla Firefox\Firefox.exe", WorkingDirectory = @"C:\Program Files\Mozilla Firefox\", Arguments = @"C:\Sample.html" }; // データクラスをコントロールにバインドする titleTextBox.DataContext = item; fileNameTextBox.DataContext = item; workingDirTextBox.DataContext = item; parameterTextBox.DataContext = item; // ReferenceCommand とイベントハンドラ結びつける CommandBinding を作成 var referenceCommandBinding = new CommandBinding(ReferenceCommand, referenceCommandBinding_Executed, referenceCommandBinding_CanExecute); // CommandBindig の登録 referenceButton.CommandBindings.Add(referenceCommandBinding); } // コマンド実行する private void referenceCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog(); bool? result = dialog.ShowDialog(this); if (result.HasValue && result.Value) { Item item = (Item)fileNameTextBox.DataContext; item.FileName = dialog.FileName; } } // コマンドを実行できるかどうか判断する private void referenceCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = fileNameTextBox.DataContext is Item; } }
XAML を修正
修正箇所にはコメントを入れています。
<!-- Window タグ内で名前空間を指定しています--> <Window x:Class="WpfSample.EditDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfSample="clr-namespace:WpfSample" Title="EditDialog" Height="400" Width="400" Background="#303030"> <Window.Resources> <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}"> <Setter Property="Margin" Value="2"/> <Setter Property="Height" Value="28"/> <Setter Property="Foreground" Value="#F0F0F0"/> <Setter Property="Background" Value="#0593E2"/> </Style> <Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="#444444"/> <Setter Property="Foreground" Value="#F0F0F0"/> <Setter Property="Margin" Value="2"/> <Setter Property="Height" Value="28"/> </Style> <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}"> <Setter Property="Margin" Value="2"/> <Setter Property="Height" Value="28"/> <Setter Property="Background" Value="#444444"/> <Setter Property="Foreground" Value="#F0F0F0"/> </Style> <Style x:Key="{x:Type Label}" TargetType="{x:Type Label}"> <Setter Property="Foreground" Value="#F0F0F0"/> </Style> </Window.Resources> <DockPanel LastChildFill="True"> <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" FlowDirection="RightToLeft"> <Button Width="100" Content="キャンセル"/> <Button Width="100" Content="OK"/> </StackPanel> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="150"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="50"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Label Grid.Column="0" Grid.Row="0" Content="名前"/> <Label Grid.Column="0" Grid.Row="1" Content="ファイル名"/> <Label Grid.Column="0" Grid.Row="2" Content="パラメータ"/> <Label Grid.Column="0" Grid.Row="3" Content="作業フォルダ"/> <Label Grid.Column="0" Grid.Row="4" Content="実行時の大きさ"/> <Label Grid.Column="0" Grid.Row="5" Content="ツールチップ"/> <Label Grid.Column="0" Grid.Row="6" Content="ショートカットキー"/> <Label Grid.Column="0" Grid.Row="7" Content="ホットキー"/> <TextBox Name="titleTextBox" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Title}"/> <TextBox Name="fileNameTextBox" Grid.Column="1" Grid.Row="1" Text="{Binding FileName}"/> <TextBox Name="parameterTextBox" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding Arguments}"/> <TextBox Name="workingDirTextBox" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="2" Text="{Binding WorkingDirectory}"/> <ComboBox Name="windowSizeComboBox" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="2" SelectedIndex="0" > <ComboBoxItem Content="通常のウィンドウ"/> <ComboBoxItem Content="最大化"/> <ComboBoxItem Content="最小化"/> </ComboBox> <TextBox Name="toolTipTextBox" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="2"/> <TextBox Name="shortcutKeyTextBox" Grid.Column="1" Grid.Row="6"/> <TextBox Name="hotKeyTextBox" Grid.Column="1" Grid.Row="7" /> <!-- 参照ボタンを押したときに実行する Command を指定--> <Button Name="referenceButton" Grid.Column="2" Grid.Row="1" Content="参照" Command="{x:Static WpfSample:EditDialog.ReferenceCommand}"/> <Button Grid.Column="2" Grid.Row="6" Content="クリア"/> <Button Grid.Column="2" Grid.Row="7" Content="クリア"/> </Grid> </DockPanel> </Window>
名前空間の指定と、ボタンを押したときに実行する Command の指定を行っています。
最後に
OpenFileDialog を表示するだけのアクションを実現するだけでも、Command を使うと結構面倒だなぁ。プログラムの規模が小さいから便利さを感じないのかも?
あと CommandBinding は XAML で記述できるけれど、エントリが長くなるので次回に持ち越します。今日はここまで。