5.2 UI を作成する
5.3.5 CommonDialogBehavior クラスを汎用的にする
前節のサンプルでは、CommonDialogBehavior クラス内部でコモンダイアログに対するタイトルやファイルフィルタな どの設定を固定値として与えていましたが、これも添付プロパティとして定義することで、XAML から指定することができ るようになります。
Title、Filter、Multiselect プロパティを添付プロパティとして定義するようにした CommonDialogBehavior クラ スは次のようになります。
コード 5.14:ダイアログのタイトルなども外部から設定できるようにした CommonDialogBehavior クラス CommonDialogBehavior.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
44 45 46 47
namespace YKWpfIntroduction.Practices.Views.Behaviors {
using Microsoft.Win32;
using System;
using System.Windows;
/// <summary>
/// コモンダイアログに関するビヘイビアを表します。
/// </summary>
internal class CommonDialogBehavior {
#region Callback 添付プロパティ
/// <summary>
/// Action<bool, string> 型の Callback 添付プロパティを定義します。
/// </summary>
public static readonly DependencyProperty CallbackProperty =
DependencyProperty.RegisterAttached("Callback", typeof(Action<bool, string>),
typeof(CommonDialogBehavior), new PropertyMetadata(null, OnCallbackPropertyChanged));
/// <summary>
/// Callback 添付プロパティを取得します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <returns>取得した値を返します。</returns>
public static Action<bool, string> GetCallback(DependencyObject target) {
return (Action<bool, string>)target.GetValue(CallbackProperty);
}
/// <summary>
/// Callback 添付プロパティを設定します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <param name="value">設定する値を指定します。</param>
public static void SetCallback(DependencyObject target, Action<bool, string> value) {
target.SetValue(CallbackProperty, value);
}
#endregion Callback 添付プロパティ
#region Title 添付プロパティ
/// <summary>
/// string 型の Title 添付プロパティを定義します。
/// </summary>
public static readonly DependencyProperty TitleProperty =
DependencyProperty.RegisterAttached("Title", typeof(string), typeof(CommonDialogBehavior), new PropertyMetadata("ファイルを開く"));
/// <summary>
/// Title 添付プロパティを取得します。
/// </summary>
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
98 99 100 101 102 103
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <returns>取得した値を返します。</returns>
public static string GetTitle(DependencyObject target) {
return (string)target.GetValue(TitleProperty);
}
/// <summary>
/// Title 添付プロパティを設定します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <param name="value">設定する値を指定します。</param>
public static void SetTitle(DependencyObject target, string value) {
target.SetValue(TitleProperty, value);
}
#endregion Title 添付プロパティ
#region Filter 添付プロパティ
/// <summary>
/// string 型の Filter 添付プロパティを定義します。
/// </summary>
public static readonly DependencyProperty FilterProperty =
DependencyProperty.RegisterAttached("Filter", typeof(string), typeof(CommonDialogBehavior), new PropertyMetadata("すべてのファイル (*.*)|*.*"));
/// <summary>
/// Filter 添付プロパティを取得します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <returns>取得した値を返します。</returns>
public static string GetFilter(DependencyObject target) {
return (string)target.GetValue(FilterProperty);
}
/// <summary>
/// Filter 添付プロパティを設定します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <param name="value">設定する値を指定します。</param>
public static void SetFilter(DependencyObject target, string value) {
target.SetValue(FilterProperty, value);
}
#endregion Filter 添付プロパティ
#region Multiselect 添付プロパティ
/// <summary>
/// bool 型の Multiselect 添付プロパティを定義します。
/// </summary>
public static readonly DependencyProperty MultiselectProperty =
DependencyProperty.RegisterAttached("Multiselect", typeof(bool), typeof(CommonDialogBehavior), new PropertyMetadata(true));
/// <summary>
/// Multiselect 添付プロパティを取得します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <returns>取得した値を返します。</returns>
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
public static bool GetMultiselect(DependencyObject target) {
return (bool)target.GetValue(MultiselectProperty);
}
/// <summary>
/// Multiselect 添付プロパティを設定します。
/// </summary>
/// <param name="target">対象とする DependencyObject を指定します。</param>
/// <param name="value">設定する値を指定します。</param>
public static void SetMultiselect(DependencyObject target, bool value) {
target.SetValue(MultiselectProperty, value);
}
#endregion Multiselect 添付プロパティ
/// <summary>
/// Callback 添付プロパティ変更イベントハンドラ /// </summary>
/// <param name="sender">イベント発行元</param>
/// <param name="e">イベント引数</param>
private static void OnCallbackPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var callback = GetCallback(sender);
if (callback != null) {
var dlg = new OpenFileDialog() {
Title = GetTitle(sender), Filter = GetFilter(sender),
Multiselect = GetMultiselect(sender), };
var owner = Window.GetWindow(sender);
var result = dlg.ShowDialog(owner);
callback(result.Value, dlg.FileName);
} } } }
この添付ビヘイビアは XAML では次のように使用できます。
コード 5.15:作成した添付プロパティを使用する
MainView.xaml 1
2 3 4 5 6 7 8 9 10 11 12 13 14
<Window x:Class="YKWpfIntroduction.Practices.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="clr-namespace:YKWpfIntroduction.Practices.Views.Behaviors"
Title="MainView" Height="300" Width="300">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="ファイル (_F)">
<MenuItem Header="開く(_O)"
Command="{Binding OpenFileCommand}"
b:CommonDialogBehavior.Title="ファイルを開く"
b:CommonDialogBehavior.Filter="画像ファイル (*.bmp; *.jpg;
*.png)|*.bmp;*.jpg;*.png|すべてのファイル (*.*)|*.*"
b:CommonDialogBehavior.Multiselect="False"
b:CommonDialogBehavior.Callback="{Binding DialogCallback}"
15 16 17 18 19 20 21 22 23 24 25 26
/>
</MenuItem>
<MenuItem Header="ヘルプ (_H)" />
</Menu>
<StatusBar DockPanel.Dock="Bottom">
</StatusBar>
<Grid Background="MediumSeaGreen">
</Grid>
</DockPanel>
</Window>
添付ビヘイビアは様々なコントロールに使い回せるというメリットがあるため、できるだけ汎用的に作成したほうが便利 です。ここではファイルを開く機能しかありませんが、ファイルを保存するためのコモンダイアログもほとんど同様のプロ パティで設定できるため、ファイルを開くモードか保存するモードかを選択させるような添付プロパティを追加し、モード によって OpenFileDialog クラスを使用するか SaveFileDialog クラスを使用するかを分岐させるようにするとなお便 利な添付ビヘイビアになるでしょう。
5.4 「終了」メニューでアプリケーションを終了させる
アプリケーションをいきなり終了されてしまうとこれまでの作業内容が保存されなかったり、ログを保存できなかったり いろいろ不便が生じます。アプリケーションを終了するときは内部でなんらかの処理をおこない、その上で終了するように したほうが良いでしょう。ここでは、ユーザーからアプリケーションを終了したいという要求を受け取ったときにどのよう に処理するかについて説明します。