WPF TextBoxへの入力制限について - TakanoriMukai/MyNotes GitHub Wiki
WPFのテキストボックスは実装から制限をかける必要がある。
(プロパティから制限を掛けられない)
※そもそもWPFでは入力「後」にValidating処理をして入力チェックを行うのが主流?
<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;
}
}
ビヘイビアをテキストボックスに設定し、右クリックの制限、 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;
}
}
<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>