注
Windows App SDK の WinUI のテキスト コントロールでは、手書きビューはサポートされていません。 この記事は、UWP アプリにのみ適用されます。
TextBox、RichEditBox、AutoSuggestBox などの UWP テキスト入力コントロールに組み込まれている手書きビュー (インクからテキストへの入力用) をカスタマイズします。
概要
UWP テキスト入力コントロールは、ユーザーがペンを使用してテキスト入力ボックスにタップしたときに手書き画面に変換することで、 Windows Ink を使用したペン入力をサポートします。
テキストは、ユーザーが手書き画面の任意の場所に書き込むときに認識され、候補ウィンドウに認識結果が表示されます。 ユーザーは、結果をタップして選択するか、提案された候補者を受け入れるための書き込みを続けることができます。 リテラル (文字単位) の認識結果は候補ウィンドウに含まれるため、認識は辞書内の単語に限定されません。 ユーザーが書き込むにつれて、受け入れられたテキスト入力は、自然な書き込み感を保持するスクリプト フォントに変換されます。
注
手書きビューは既定で有効になっていますが、コントロールごとに無効にして、代わりにテキスト入力パネルに戻すことができます。
ユーザーは、標準のジェスチャとアクションを使用してテキストを編集できます。
- ストライキスルー または スクラッチアウト - 単語または単語の一部を削除するために引き抜く
- 結合 - 単語間に円弧を描画して、単語間のスペースを削除します
- insert - キャレット記号を描画してスペースを挿入する
- overwrite - 既存のテキストに書き込んで置き換える
手書きビューを無効にする
組み込みの手書きビューは、既定で有効になっています。
アプリケーションで既に同等のインクテキスト変換機能を提供している場合、またはテキスト入力エクスペリエンスが手書きでは使用できない何らかの種類の書式設定や特殊文字 (タブなど) に依存している場合は、手書きビューを無効にすることができます。
この例では、TextBox コントロールの IsHandwritingViewEnabled プロパティを false に設定して、手書きビューを無効にします。 手書きビューをサポートするすべてのテキスト コントロールは、同様のプロパティをサポートします。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen"
IsHandwritingViewEnabled="False">
</TextBox>
手書きビューの配置を指定する
手書きビューは、基になるテキスト コントロールの上にあり、ユーザーの手書き設定に合わせてサイズが設定されます ( 「設定 -> Bluetooth & devices -> Pen 」および「Windows Ink -> Handwriting -> Font size」を参照)。 また、ビューは、テキスト コントロールとそのアプリ内での位置を基準にして自動的に配置されます。
アプリケーション UI は、より大きなコントロールに合わせてリフローされず、重要な UI 要素を覆い隠す可能性があります。
次のスニペットは、TextBoxHandwritingView の PlacementAlignment プロパティを使用して、手書きビューの配置に使用する基になるテキスト コントロール上のアンカーを指定する方法を示しています。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen">
<TextBox.HandwritingView>
<HandwritingView PlacementAlignment="TopLeft"/>
</TextBox.HandwritingView>
</TextBox>
オートコンプリート候補を無効にする
テキスト候補ポップアップは、既定で有効になっています。 主要な候補が正しくない場合にユーザーが選択できる上位のインク認識候補の一覧が提供されます。
アプリケーションで堅牢なカスタム認識機能が既に提供されている場合は、次の例に示すように 、AreCandidatesEnabled プロパティを使用して組み込みの提案を無効にすることができます。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen">
<TextBox.HandwritingView>
<HandwritingView AreCandidatesEnabled="False"/>
</TextBox.HandwritingView>
</TextBox>
手書きフォントの基本設定を使用する
ユーザーは、インク認識に基づいてテキストをレンダリングするときに使用する手書きベースのフォントの定義済みのコレクションから選択できます ( 「設定 」を参照してください -> Bluetooth & デバイス -> ペン & Windows Ink -> Handwriting -> Font)。
アプリはこの設定にアクセスし、テキスト コントロールで認識されたテキストに対して選択したフォントを使用できます。
この例では、TextBox の TextChanged イベントをリッスンし、HandwritingView からテキストの変更が発生した場合はユーザーの選択したフォントを適用します (そうでない場合は既定のフォント)。
private void SampleTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
((TextBox)sender).FontFamily =
((TextBox)sender).HandwritingView.IsOpen ?
new FontFamily(PenAndInkSettings.GetDefault().FontFamilyName) :
new FontFamily("Segoe UI");
}
複合コントロールで HandwritingView にアクセスする
TextBox コントロールまたは RichEditBox コントロール (AutoSuggestBox など) を使用する複合コントロールでも、HandwritingView がサポートされます。
複合コントロールの HandwritingView にアクセスするには、 VisualTreeHelper API を使用します。
次の XAML スニペットは 、AutoSuggestBox コントロールを表示します。
<AutoSuggestBox Name="SampleAutoSuggestBox"
Height="50" Width="500"
PlaceholderText="Auto Suggest Example"
FontSize="16" FontFamily="Segoe UI"
Loaded="SampleAutoSuggestBox_Loaded">
</AutoSuggestBox>
対応する分離コードでは、AutoSuggestBox で HandwritingView を無効にする方法を示します。
まず、要素の Loaded イベントを処理し、
FindInnerTextBox関数を呼び出してビジュアル ツリーのトラバーサルを開始します。private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e) { if (FindInnerTextBox((AutoSuggestBox)sender)) autoSuggestInnerTextBox.IsHandwritingViewEnabled = false; }FindInnerTextBox関数では、FindVisualChildByName関数を呼び出してビジュアル ツリー (AutoSuggestBox 以降) を反復処理します。private bool FindInnerTextBox(AutoSuggestBox autoSuggestBox) { if (autoSuggestInnerTextBox == null) { // Cache textbox to avoid multiple tree traversals. autoSuggestInnerTextBox = (TextBox)FindVisualChildByName<TextBox>(autoSuggestBox); } return (autoSuggestInnerTextBox != null); } ```最後に、
FindVisualChildByName関数は 、TextBox が取得されるまでビジュアル ツリーを反復処理します。private FrameworkElement FindVisualChildByName<T>(DependencyObject obj) { FrameworkElement element = null; int childrenCount = VisualTreeHelper.GetChildrenCount(obj); for (int i = 0; (i < childrenCount) && (element == null); i++) { FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(obj, i); if ((child.GetType()).Equals(typeof(T)) || (child.GetType().GetTypeInfo().IsSubclassOf(typeof(T)))) { element = child; } else { element = FindVisualChildByName<T>(child); } } return (element); } ```
HandwritingView の位置を変更する
場合によっては、 HandwritingView に含まれていない UI 要素を確実に含める必要がある場合があります。
ここでは、ディクテーションをサポートする TextBox を作成します (TextBox とディクテーション ボタンを StackPanel に配置することによって実装されます)。
StackPanel が TextBox より大きくなりましたので、 HandwritingView ではすべての複合コントロールが隠されない可能性があります。
これに対処するには、 HandwritingView の PlacementTarget プロパティを、配置先の UI 要素に設定します。
<StackPanel Name="DictationBox"
Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="1" BorderBrush="DarkGray"
Height="55" Width="500" Margin="50">
<TextBox Name="DictationTextBox"
Width="450" BorderThickness="0"
FontSize="24" VerticalAlignment="Center">
<TextBox.HandwritingView>
<HandwritingView PlacementTarget="{Binding ElementName=DictationBox}"/>
</TextBox.HandwritingView>
</TextBox>
<Button Name="DictationButton"
Height="48" Width="48"
FontSize="24"
FontFamily="Segoe MDL2 Assets"
Content=""
Background="White" Foreground="DarkGray" Tapped="DictationButton_Tapped" />
</StackPanel>
HandwritingView のサイズを変更する
HandwritingView のサイズを設定することもできます。これは、ビューが重要な UI を隠さないことを確認する必要がある場合に便利です。
前の例と同様に、ディクテーションをサポートする TextBox を作成します (TextBox とディクテーション ボタンを StackPanel に配置することによって実装されます)。
この場合、HandwritingView のサイズを変更して、ディクテーション ボタンが表示されるようにします。
これを行うには、 HandwritingView の MaxWidth プロパティを、隠す UI 要素の幅にバインドします。
<StackPanel Name="DictationBox"
Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="1"
BorderBrush="DarkGray"
Height="55" Width="500"
Margin="50">
<TextBox Name="DictationTextBox"
Width="450"
BorderThickness="0"
FontSize="24"
VerticalAlignment="Center">
<TextBox.HandwritingView>
<HandwritingView
PlacementTarget="{Binding ElementName=DictationBox}"
MaxWidth="{Binding ElementName=DictationTextBox, Path=Width"/>
</TextBox.HandwritingView>
</TextBox>
<Button Name="DictationButton"
Height="48" Width="48"
FontSize="24"
FontFamily="Segoe MDL2 Assets"
Content=""
Background="White" Foreground="DarkGray"
Tapped="DictationButton_Tapped" />
</StackPanel>
カスタム UI の位置を変更する
情報ポップアップなどのテキスト入力に応答して表示されるカスタム UI がある場合は、手書きビューが隠されないように、その UI の位置を変更する必要がある場合があります。
次の例は、HandwritingView の Opened、Closed、SizeChanged イベントをリッスンして、ポップアップの位置を設定する方法を示しています。
private void Search_HandwritingViewOpened(
HandwritingView sender, HandwritingPanelOpenedEventArgs args)
{
UpdatePopupPositionForHandwritingView();
}
private void Search_HandwritingViewClosed(
HandwritingView sender, HandwritingPanelClosedEventArgs args)
{
UpdatePopupPositionForHandwritingView();
}
private void Search_HandwritingViewSizeChanged(
object sender, SizeChangedEventArgs e)
{
UpdatePopupPositionForHandwritingView();
}
private void UpdatePopupPositionForHandwritingView()
{
if (CustomSuggestionUI.IsOpen)
CustomSuggestionUI.VerticalOffset = GetPopupVerticalOffset();
}
private double GetPopupVerticalOffset()
{
if (SearchTextBox.HandwritingView.IsOpen)
return (SearchTextBox.Margin.Top + SearchTextBox.HandwritingView.ActualHeight);
else
return (SearchTextBox.Margin.Top + SearchTextBox.ActualHeight);
}
HandwritingView コントロールのテンプレートを再作成する
すべての XAML フレームワーク コントロールと同様に、 HandwritingView の視覚的構造と視覚的な動作の両方を、特定の要件に合わせてカスタマイズできます。
カスタム テンプレートを作成する完全な例については、 カスタム トランスポート コントロールの作成方法または カスタム編集コントロールのサンプルを参照してください。
Windows developer