WPFで優れたUIを作成するInputMan for WPF
これまで、WindowsアプリケーションのUIを構築する方法は、Windowsフォームを使用した開発が中心でしたが、より良いUI設計を考えると、今後はWPFを採用した開発が主流となっていくでしょう。しかし現実には、WindowsフォームからWPFへの移行は、思うように進んではいないのが実情です。XAMLが難しいなど、色々な要因があると思います。それ以外にも、Windowsフォーム向けに販売されているコンポーネント製品の出来が良いため、従来のWindowsフォームに拡張性を持たせた優れたUIを提供でき、WPFに移行する必要がないと判断されている場合もあるのではないでしょうか。
では、そんなコンポーネント群がWPF向けに提供されたらどうでしょう。「InputMan for WPF」はWindowsフォームでの日本語入力環境を飛躍的に向上させ続けてきた「InputMan」のWPF版です。InputMan for WPFを使用すると、WPFを採用した業務アプリケーションのUI開発をスムーズに行うことができます。
InputMan for WPFの構成
InputMan for WPFには次のようなコンポーネントが収録されています。
- テキスト
- マスク
- 日付
- 数値
- カレンダー
- 電卓
- 検証インジケータ
- IME管理
- 書式コンバータ
主な機能としては次のような機能が実装されています。
- 入力書式と出力書式の個別設定
- 和暦入力と表示
- 半角・全角、ひらがな・カタカナなどの文字種自動変換
- 入力範囲チェック
- 検証エラー通知
- 未入力時の代替テキスト(いわゆるウォーターマーク)表示
- フィールド単位のスタイル設定
- テーマテンプレート対応
- 複数行テキスト入力時の行間罫線および最大行数制限
- ふりがな自動取得
多岐に渡る機能が用意されているため、自分が使いたい機能が実装されているかが判断しづらいかも知れません。そこで、お客様情報の登録用業務アプリをサンプルで作成して、標準のコンポーネントとどれくらい使い勝手が違うのかを検証してみたいと思います。
サンプル画面のデザイン
今回の比較では、入力フィールド以外は共通のデザインを採用します。以下のXAMLで定義された雛形をもとに、標準コンポーネントを使用してできる画面と、InputMan for WPFを使用してできる画面とを比較していきたいと思います。
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="300" Width="600"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Image x:Name="Icon_Image" Grid.RowSpan="7" Margin="5" VerticalAlignment="Top" /> <TextBlock Grid.Row="0" Grid.Column="1" Padding="5" Text="氏名" /> <TextBlock Grid.Row="1" Grid.Column="1" Padding="5" Text="フリガナ" /> <TextBlock Grid.Row="2" Grid.Column="1" Padding="5" Text="郵便番号" /> <TextBlock Grid.Row="3" Grid.Column="1" Padding="5" Text="住所" /> <TextBlock Grid.Row="4" Grid.Column="1" Padding="5" Text="生年月日" /> <TextBlock Grid.Row="5" Grid.Column="1" Padding="5" Text="備考" /> …(*)… </Grid> </Window>
今回のサンプルには、業務アプリの基本レイアウトとしてタイトルと入力フィールドが並べやすいGridを採用しています(Grid以外にStackPanelやCanvasなども指定できます)。リスト1には、まだ入力フィールドを配置していませんが、次ページから「Grid.Column="2"
」として入力フィールド用のコントロールを配置していきます。
標準コンポーネントでお客様情報登録画面を作成
まず、標準コンポーネントだけを使って画面を作成してみました。入力欄に影を付けたくらいで特殊なことは何もしていないレイアウトです。
標準コンポーネントでは、文字数の制限はありますが、文字種の制限や自動変更がないため、XAML定義だけでは希望する文字種で入力されるとは限りません。
InputMan for WPFでお客様情報登録画面を作成
では、次に基本レイアウトにInputManを配置して画面をデザインしてみます。InputManを使うためには、ツールボックスにInputManのコンポーネントを追加します。
続いて、ツールボックスからフォームエディタに使用するコントロールをドラッグ&ドロップします。今回のサンプルでは、氏名、フリガナ、住所についてはGcTextBoxを使います。郵便番号にはGcMask、生年月日にはGcDate、備考にはGcTextBoxをMultiLine指定で使います。
氏名欄
前ページのリスト1「…(*)…
」の部分に、次のXAML定義を記述して、氏名欄を定義します。
InputManを使った氏名欄では、標準テキストボックスで実現できなかった文字種制限を実現しています。また、未入力時に「必須項目」と表示して、氏名欄が必須項目であることがわかるようにしています。さらに、氏名欄で漢字入力をした時の漢字の読みを、フリガナ欄にフリガナとして自動転記もするようにして、入力の負荷を軽減できるようにします。
<im:GcTextBox Grid.Row="0" Grid.Column="2" Name="Name_TextBox" WatermarkDisplayNull="必須項目" WatermarkDisplayNullForeground="#80000000" WatermarkNull="本名を入力してください。" WatermarkNullForeground="#80000000" Format="aAZ" MaxLength="16" HighlightText="True" VerticalContentAlignment="Stretch" VerticalAlignment="Center" im:GcImeManager.ReadingString="{Binding Kana, Mode=TwoWay}" im:GcImeManager.ReadingStringKanaMode="KatakanaHalf" im:GcImeManager.ReadingStringOutputMode="Append" > <im:GcTextBox.Effect> <DropShadowEffect/> </im:GcTextBox.Effect> <im:GcTextBox.Text> <Binding Path="Name" Mode="TwoWay"/> </im:GcTextBox.Text> </im:GcTextBox>
-
「
Grid.Row="0" Grid.Column="2"
」にはName_TextBoxという名前でGcTextBoxコントロールを配置します。 - WatermarkDisplayNullプロパティにより、入力欄に値が設定されていないときの表示を指定しています。コントロールがフォーカスを得た時、入力欄に値が設定されていない場合は、WatermarkNullプロパティの内容が表示されます。それぞれ少し薄い色で表示することで、実際の入力値と区別がつくようにしています。
-
「
Format="aAZ"
」としているので英小文字、英大文字、空白、全角文字すべてが入力できるように設定しています。また、MaxLengthプロパティに16を指定し、最大文字数を16文字に制限しています。 - GcImeManagerを指定して、IMEの入力をGcImeManagerに送信しています。
- GcTextBox.Effectを指定して、影付きの入力欄にします。
-
「
<Binding Path="Name" Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのNameプロパティ値と連携します。
フリガナ欄
同じように、フリガナ欄として次のXAML定義をリスト1に追記します。
フリガナ欄も、InputManを使えば入力できる文字種を半角カナのみに限定することが可能です。同時に、全角カナやひらがなを入力した場合は、自動的に半角カナに変換する機能もInputManのプロパティで実現できるため、操作性の良い入力画面が作成できます。
<im:GcTextBox Grid.Row="1" Grid.Column="2" Name="Kana_TextBox" WatermarkDisplayNull="必須項目" WatermarkDisplayNullForeground="#80000000" WatermarkNull="フリガナを入力してください。" WatermarkNullForeground="#80000000" VerticalContentAlignment="Stretch" VerticalAlignment="Center" Format="K" MaxLength="32" HighlightText="True" > <im:GcTextBox.Effect> <DropShadowEffect/> </im:GcTextBox.Effect> <im:GcTextBox.Text> <Binding Path="Kana" Mode="TwoWay" /> </im:GcTextBox.Text> </im:GcTextBox>
-
「
Grid.Row="1" Grid.Column="2"
」にはKana_TextBoxという名前でGcTextBoxコントロールを配置します。 - WatermarkDisplayNullプロパティにより、入力欄に値が設定されていないときの表示を指定しています。コントロールがフォーカスを得た時、入力欄に値が設定されていない場合は、WatermarkNullプロパティの内容が表示されます。それぞれ少し薄い色で表示することで、実際の入力値と区別がつくようにしています。
-
「
Format="K"
」としているので半角カナのみが入力できます。また、デフォルトでAutoConvertが「True」になっているので全角カナや全角ひらがなの入力は自動的に半角カナに変換されます。 - GcTextBox.Effectを指定して影付きの入力欄にします。
-
「
<Binding Path="Kana" Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのKanaプロパティ値と連携します。
郵便番号欄
郵便番号欄は「3桁-4桁」の入力欄が明確にわかるように、InputManの機能を使って各欄を四角く明示するデザインを採用します。
<Grid.Resources> <Style x:Key="StyleBase" TargetType="im:MaskPatternField"> <Setter Property="BorderBrush" Value="Red" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="PromptChar" Value=" " /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> </Style> <Style x:Key="Style1" BasedOn="{StaticResource StyleBase}" TargetType="im:MaskPatternField"> <Setter Property="Width" Value="20" /> </Style> <Style x:Key="Style2" BasedOn="{StaticResource StyleBase}" TargetType="im:MaskPatternField"> <Setter Property="Width" Value="18" /> </Style> </Grid.Resources> : (中略) : <im:GcMask Grid.Row="2" Grid.Column="2" VerticalAlignment="Center"> <im:GcMask.FieldSet> <im:MaskFieldSet> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style1}" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style1}" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style1}" /> <im:MaskLiteralField Text="-" Margin="2, 0, 2, 0" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style2}" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style2}" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style2}" /> <im:MaskPatternField MinLength="1" MaxLength="1" Pattern="\D" Style="{StaticResource Style2}" /> </im:MaskFieldSet> </im:GcMask.FieldSet> <im:GcMask.Effect> <DropShadowEffect/> </im:GcMask.Effect> <im:GcMask.Text> <Binding Path="PostCode" Mode="TwoWay" /> </im:GcMask.Text> </im:GcMask>
- 入力欄用のStyleをリソースとして定義しておきます。
-
「
Grid.Row="2" Grid.Column="2"
」にはPostCode_TextBoxという名前でGcMaskコントロールを配置します。 - GcMask.Effectを指定して影付きの入力欄にします。
-
「
<Binding Path="PostCode" Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのPostCodeプロパティ値と連携します。
住所欄
住所欄は、標準的な文字数であれば画面に収まる大きさに欄をデザインしておき、場合によっては欄を超える入力も可能にした場合の省略文字の利用を想定しています。このような想定は、InputManのGcTextBoxが備えているEllipsis機能を使い、XAML定義だけで簡単に実現できます。もちろん未入力時に「必須項目」と表示したり、文字種の制限をするのも、XAML定義だけで実現が可能です。
<im:GcTextBox Grid.Row="3" Grid.Column="2" Name="Address_TextBox" WatermarkDisplayNull="必須項目" WatermarkDisplayNullForeground="#80000000" WatermarkNull="住所を入力してください。" WatermarkNullForeground="#80000000" Format="aAZ" MaxLength="40" HighlightText="True" VerticalContentAlignment="Stretch" VerticalAlignment="Center" ShowOverflowTip="True" Ellipsis="EllipsisPath" EllipsisString="…(略)…" > <im:GcTextBox.Effect> <DropShadowEffect/> </im:GcTextBox.Effect> <im:GcTextBox.Text> <Binding Path="Address" Mode="TwoWay"/> </im:GcTextBox.Text> </im:GcTextBox>
-
「
Grid.Row="3" Grid.Column="2"
」にはAddress_TextBoxという名前でGcTextBoxコントロールを配置します。 -
「
ShowOverfolwTip="True"
」を指定してマウスを持っていくとツールチップ表示で枠外の部分まで値を表示するように設定します。 - EllipsisプロパティとEllipsisStringプロパティを設定し、枠内に値が収まらなかったときは「…(略)…」と中略表示するように設定します。
- GcMask.Effectを指定して影付きの入力欄にします。
-
「
<Binding Path="Address" Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのAddressプロパティ値と連携します。
生年月日欄
生年月日欄については、yyyy年MM月dd日の形式での入力を実現しています。
<im:GcDateTime Grid.Row="4" Grid.Column="2" Name="Birth_Date" VerticalContentAlignment="Stretch" VerticalAlignment="Center" WatermarkDisplayNull="必須項目" WatermarkDisplayNullForeground="#80000000" WatermarkNull="生年月日を入力してください。" WatermarkNullForeground="#80000000" HighlightText="Field" > <im:GcDateTime.DisplayFieldSet> <im:DateDisplayFieldSet> <im:DateYearDisplayField /> <im:DateLiteralDisplayField Text="年" /> <im:DateMonthDisplayField ShowLeadingZero="True" /> <im:DateLiteralDisplayField Text="月" /> <im:DateDayDisplayField ShowLeadingZero="True" /> <im:DateLiteralDisplayField Text="日" /> </im:DateDisplayFieldSet> </im:GcDateTime.DisplayFieldSet> <im:GcDateTime.FieldSet> <im:DateFieldSet> <im:DateYearField /> <im:DateLiteralField Text="年" /> <im:DateMonthField /> <im:DateLiteralField Text="月" /> <im:DateDayField /> <im:DateLiteralField Text="日" /> </im:DateFieldSet> </im:GcDateTime.FieldSet> <im:GcDateTime.Effect> <DropShadowEffect/> </im:GcDateTime.Effect> <im:GcDateTime.Value> <Binding Path="BirthDay" Mode="TwoWay"/> </im:GcDateTime.Value> </im:GcDateTime>
-
「
Grid.Row="4" Grid.Column="2"
」にはBirth_Dateという名前でGcDateTimeコントロールを配置します。 - WatermarkDisplayNullプロパティにより、入力欄に値が設定されていないときの表示を指定しています。コントロールがフォーカスを得た時、入力欄に値が設定されていない場合は、WatermarkNullプロパティの内容が表示されます。それぞれ少し薄い色で表示することで、実際の入力値と区別がつくようにしています。
- GcTextBox.Effectを指定して影付きの入力欄にします。
-
「
<Binding Path=" BirthDay " Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのBirthDayプロパティ値と連携します。
GcDateTimeコントロールは、DisplayFieldSetプロパティ(表示書式)、FieldSetプロパティ(入力書式)を設定するだけで、簡単に和暦表示などを行えます。表示と入力で、個別に書式を設定することもできます。
備考欄
備考欄は、複数行が入力できるようになっています。InputManを使った場合、各行を点線で区切り、見栄えのいい複数行入力欄を実現することが可能です。
<im:GcTextBox Grid.Row="5" Grid.Column="2" Name="Comment_TextBox" WatermarkDisplayNull="任意項目" WatermarkDisplayNullForeground="#80000000" WatermarkNull="連絡事項を入力してください。" WatermarkNullForeground="#80000000" Multiline="True" MaxLength="2000" MaxLengthUnit="Byte" MaxLineCount="10" GridLineStyle="Dotted" GridLineBrush="Black" TextWrapping="Wrap" HighlightText="True" VerticalScrollBarVisibility="Auto" > <im:GcTextBox.Effect> <DropShadowEffect/> </im:GcTextBox.Effect> <im:GcTextBox.Text> <Binding Path="Comment" Mode="TwoWay"/> </im:GcTextBox.Text> </im:GcTextBox>
-
「
Grid.Row="5" Grid.Column="2"
」にはComment_TextBoxという名前でGcTextBoxコントロールを配置します。 - WatermarkDisplayNullプロパティにより、入力欄に値が設定されていないときの表示を指定しています。コントロールがフォーカスを得た時、入力欄に値が設定されていない場合は、WatermarkNullプロパティの内容が表示されます。それぞれ少し薄い色で表示することで実際の入力値と区別がつくようにしています。
-
「
Multiline="True" MaxLength="2000" MaxLengthUnit="Byte"
」として、複数行サポート、最大2000バイトまで入力可能にします。 - GcTextBox.Effectを指定して影付きの入力欄にします。
-
「
<Binding Path="Comment" Mode="TwoWay"/>
」をTextプロパティに指定して、GridのDataContextに割り当てたクラスのCommentプロパティ値と連携します。
まとめ
WPFを使った画面は、標準コントロールだけで作成した場合でもWindowsフォームとは一味違ったデザインの画面が作成できます。しかし、InputMan for WPFを使えば、複数行表示の罫線や行数制限などさらに一味違ったデザインを実装できます。
そして実際に業務アプリを作成してみると、文字種限定や自動変換という機能は入力後のチェックコードなどを大幅に削減できるばかりではなく、利用者にとってもチェック後に入力し直すことがなく、全体的な操作性の向上につながります。
もちろん、標準コントロールを駆使してウォータマークなどの機能を作成することもできますが、InputManによりその時間を他の使い勝手の向上に充てられるのならばそれに越したことはないのではないでしょうか。