WPFでInkCanvasにTextBoxを追加してみる
開発環境
- Visual Studio 2017 (C#)
- Visual Studioの拡張機能の「Prism Template Pack」
- Prism.Core 6.3.0
- Prism.Unity 6.3.0
- Prism.Wpf 6.3.0
- CommonServiceLocator 1.3.0
- Unity 4.0.1
- MahApps.Metro 1.5.0
初めに
前回のプロジェクトを使用するのでPrismを使っていますが、ViewModel側で記述する必要はない処理ですが、他のコマンドと合わせるためにViewModel側に記述しています。
※ 以前に作成した「WPFでInkCanvasを使ってみる」で作成したプロジェクトを使用しますので、途中までは、そちらを確認してください。
参考
HIRO'sさんのBlog
HIRO's.NET http://blog.hiros-dot.net/
人体図画像をお借りしました。
フリーイラスト http://www.sharots.com/ai.html
説明省略部分
「Prism Template Pack」のインストール
「MahApps」のインストール
「Prism Template Pack」のプロジェクト作成
「InkCanvas」の各種コマンド操作の実装
※「Prism Template Pack」のインストールは、以前の記事を参考にしてください。
PrismとUnityを使うWPFプロジェクトテンプレートを使ってみる
※「InkCanvas」の各種コマンド操作の実装は、以前の記事を参考にしてください。
WPFでInkCanvasを使ってみる
「MainUc.xaml」にコントロールを追加
<Button Content="テキスト追加" Command="{Binding AddTextCommand}" CommandParameter="{Binding ElementName=inkCanvas}"/>
今回もViewModel側でInkCanvasを使用するため、「CommandParameter」にInkCanvas名を入れいています。
「MainUcViewModel.cs」にDelegateCommandを追加
/// <summary>
/// テキストボタンコマンド
/// </summary>
private DelegateCommand<InkCanvas> addTextCommand;
public DelegateCommand<InkCanvas> AddTextCommand =>
addTextCommand ?? (addTextCommand = new DelegateCommand<InkCanvas>(AddTextCommandExectute));
※DelegateCommandについて補足
※「Prism Template Pack」をVisualStudioに拡張済みであれば、「cmdg」と入力すれば、簡単に上記のDelegateCommandが作成できます。
cmdg
private DelegateCommand<string> fieldNameCommand;
public DelegateCommand<string> CommandNameCommand =>
fieldNameCommand ?? (fieldNameCommand = new DelegateCommand<string>(CommandName, CanCommandName));
このように簡単にパラメータ付のDelegateCommandが作成されるので、fieldNameとCommandNameを変更するだけ済みます。
「MainUcViewModel.cs」にTextBoxの追加処理を追加
/// <summary>
/// TextBoxの追加処理
/// </summary>
/// <param name="inkCanvas"></param>
private void AddTextCommandExectute(InkCanvas inkCanvas)
{
InkEditingMode = InkCanvasEditingMode.None;
// TextBoxの追加
TextBox newTextBox = new TextBox();
newTextBox.Text = "入力してください";
newTextBox.FontSize = PenSize;
newTextBox.Foreground = new SolidColorBrush(Colors.Green);
newTextBox.Background = Brushes.Transparent;
newTextBox.BorderBrush = Brushes.Transparent;
newTextBox.SelectAll();
inkCanvas.Children.Add(newTextBox);
// TextBoxの表示位置
InkCanvas.SetTop(newTextBox, 5);
InkCanvas.SetLeft(newTextBox, 5);
// フォーカスの設定
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(newTextBox), newTextBox);
// IMEの変更
InputMethod.Current.ImeState = InputMethodState.On;
}
デバッグ実行
デバッグを実行すると以下のようになります。
といった感じで、TextBoxの追加と選択が可能になりました。
なお、TextBlockやRichTextでも可能です。
完成かと思いきや。。。。
InkCanvasの子要素でTextBoxを追加して、表示できるところまで確認できましたが、致命的な問題が発生しました。
前回の記事で作成したStrokeを画像ファイルやisfファイルへの保存する方法のままですと、追加したTextBoxが認識されないため、保存ができません。
理由としては、TextBoxをStrokeCollectionに変換していないからです。
そもそもStrokeCollectionへの変換方法がわからなかったので、どうするべきか模索中です。
とりあえず、今回は画面に表示するところまでとしています。