WPF TextBoxへの入力制限について - TakanoriMukai/MyNotes GitHub Wiki

入力制限をかける

WPFのテキストボックスは実装から制限をかける必要がある。
(プロパティから制限を掛けられない)
※そもそもWPFでは入力「後」にValidating処理をして入力チェックを行うのが主流?

方法1.コードビハインドで制限する

xaml

        <TextBox x:Name="textBox1"
                 InputMethod.IsInputMethodEnabled="False"
                 PreviewTextInput="textBoxPrice_PreviewTextInput"
                 CommandManager.PreviewExecuted="textBoxPrice_PreviewExecuted"/>

コードビハインド

        private void textBoxPrice_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            // 0-9、半角文字のみ ※ただし半角SPは入力可能
            e.Handled = !new Regex("[0-9|a-z|A-Z]").IsMatch(e.Text);
        }
        private void textBoxPrice_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            // 貼り付けを許可しない
            if (e.Command == ApplicationCommands.Paste)
            {
                e.Han= true;
            }
        }

方法2.ビヘイビアを使う

ビヘイビアをテキストボックスに設定し、右クリックの制限、 Ctrl+V操作の制限を行う。

事前準備

以下を参照に追加
・Microsoft.Expression.Interactions ・System.Windows.Interactivity

ビヘイビアの実装

    public class TextBoxBehavior : Behavior<TextBox>
    {
        // 直前の操作でCTRL+Vによるペーストを行ったか
        private bool isCommandPaste = false;

        // テキストボックスの文字列保持用変数
        private string textDataBeforePaste = "";

        /// <summary>
        /// 対象となるUI要素にBehaviorがアタッチされた時の処理
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            DataObject.AddPastingHandler(AssociatedObject, OnPaste);
            AssociatedObject.TextChanged += OnTextChanged;
            AssociatedObject.MouseRightButtonUp += OnMouseRightButtonUp;
        }

        /// <summary>
        /// 対象となるUI要素からBehaviorがデタッチされた時の処理
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();
            DataObject.RemovePastingHandler(AssociatedObject, OnPaste);
            AssociatedObject.TextChanged -= OnTextChanged;
            AssociatedObject.MouseRightButtonUp -= OnMouseRightButtonUp;
        }

        /// <summary>
        /// テキストが変更された時に呼ばれる処理
        /// 変更原因がペーストの場合、保持しておいた内容と入れ替える
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            var textBox = e.Source as TextBox;
            Console.WriteLine("OnTextChanged");
            if (isCommandPaste)
            {
                textBox.Text = textDataBeforePaste;
                isCommandPaste = false;
            }
        }

        /// <summary>
        /// ペースト時に呼ばれる処理
        /// ペースト直前に入力されていた内容を保持する
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnPaste(object sender, DataObjectPastingEventArgs e)
        {
            Console.WriteLine("OnPaste");
            isCommandPaste = true;
            textDataBeforePaste = AssociatedObject.Text;
        }

        /// <summary>
        /// マウス右ボタンクリック時の処理
        /// クリックイベントを無効化する
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine("OnMouseRightButtonUp");
            e.Handled = true;
        }
    }

xaml

<Window x:Class="LINQtest01.MainWindow"
        ...
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:local="clr-namespace:<ビヘイビアのnamespace>"
        Name="mainWindow">

        <TextBox x:Name="textBox" 
                 InputMethod.IsInputMethodEnabled="False"> // IMEの無効化はxaml側で行う
            <i:Interaction.Behaviors>
                <local:TextBoxBehavior/>
            </i:Interaction.Behaviors>
</Window>
⚠️ **GitHub.com Fallback** ⚠️