1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[WPF][XAML]InkCanvasにTextBoxを追加してみる

Last updated at Posted at 2017-12-08

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」にコントロールを追加

MainUc.xaml
<Button Content="テキスト追加" Command="{Binding AddTextCommand}" CommandParameter="{Binding ElementName=inkCanvas}"/>

今回もViewModel側でInkCanvasを使用するため、「CommandParameter」にInkCanvas名を入れいています。

「MainUcViewModel.cs」にDelegateCommandを追加

MainUcViewModel.cs
        /// <summary>
        /// テキストボタンコマンド
        /// </summary>
        private DelegateCommand<InkCanvas> addTextCommand;
        public DelegateCommand<InkCanvas> AddTextCommand =>
            addTextCommand ?? (addTextCommand = new DelegateCommand<InkCanvas>(AddTextCommandExectute));

※DelegateCommandについて補足

※「Prism Template Pack」をVisualStudioに拡張済みであれば、「cmdg」と入力すれば、簡単に上記のDelegateCommandが作成できます。

MainUcViewModel.cs(cmdg入力後Tabキーを2回押す前)
cmdg
MainUcViewModel.cs(cmdg入力後Tabキーを2回押した後)
        private DelegateCommand<string> fieldNameCommand;
        public DelegateCommand<string> CommandNameCommand =>
            fieldNameCommand ?? (fieldNameCommand = new DelegateCommand<string>(CommandName, CanCommandName));

このように簡単にパラメータ付のDelegateCommandが作成されるので、fieldNameとCommandNameを変更するだけ済みます。

「MainUcViewModel.cs」にTextBoxの追加処理を追加

MainUcViewModel.cs
        /// <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;

        }

デバッグ実行

デバッグを実行すると以下のようになります。
1512705436iFZVXm1fsil6xJi1512705432.gif
といった感じで、TextBoxの追加と選択が可能になりました。
なお、TextBlockやRichTextでも可能です。

完成かと思いきや。。。。

InkCanvasの子要素でTextBoxを追加して、表示できるところまで確認できましたが、致命的な問題が発生しました。
前回の記事で作成したStrokeを画像ファイルやisfファイルへの保存する方法のままですと、追加したTextBoxが認識されないため、保存ができません。
理由としては、TextBoxをStrokeCollectionに変換していないからです。
そもそもStrokeCollectionへの変換方法がわからなかったので、どうするべきか模索中です。
とりあえず、今回は画面に表示するところまでとしています。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?