none
TextBox で添付ビヘイビアを使ったところ、IME と干渉するのか重大エラーが!

    質問

  • いつもお世話になっております。質問ばかりですみませんが、またまた IME に関する質問です。

    入力を全角カタカナ・全半角英数および全角記号のみに制限する TextBox 用の添付ビヘイビアを作成しました。

    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApplication1 {
    
    	class TextBoxBehaviors {
    		/// <summary>
    		/// True なら入力を全角カタカナと英数および全角記号のみに制限します。
    		/// </summary>
    		public static readonly DependencyProperty IsKatakanaProperty =
    
    			DependencyProperty.RegisterAttached(
    				"IsKatakana", typeof(bool),
    				typeof(TextBoxBehaviors),
    				new UIPropertyMetadata(false, new PropertyChangedCallback(IsKatakanaChanged))
    			);
    
    		[AttachedPropertyBrowsableForType(typeof(TextBox))]
    		public static bool GetIsKatakana(DependencyObject obj) {
    			return (bool)obj.GetValue(IsKatakanaProperty);
    		}
    
    		[AttachedPropertyBrowsableForType(typeof(TextBox))]
    		public static void SetIsKatakana(DependencyObject obj, bool value) {
    			obj.SetValue(IsKatakanaProperty, value);
    		}
    
    		private static void IsKatakanaChanged
    			(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
    			var textBox = sender as TextBox;
    			if (textBox == null) return;
    
    			// 設定された値を見てイベントを登録・削除 
    			textBox.TextChanged -= OnTextKanaChanged;
    			var newValue = (bool)e.NewValue;
    			if (newValue) {
    				textBox.TextChanged += OnTextKanaChanged;
    			}
    		}
    
    
    		private static void OnTextKanaChanged(object sender, TextChangedEventArgs e) {
    			var textBox = sender as TextBox;
    			if (textBox == null) return;
    			textBox.Text = CheckKana(textBox.Text);
    		}
    
    		private static string CheckKana(string value) {
    			var ret = string.Empty;
    			if (string.IsNullOrEmpty(value)) return ret;
    
    			// 正規表現は暫定・・・
    			var reg = new Regex(@"\p{IsHiragana}|\p{IsCJKUnifiedIdeographs}|[。-゚]|[!-/]");
    			ret = reg.Replace(value, ((Match m) => string.Empty));
    			return ret;
    		}
    	}
    }
    

    XAML を以下のように定義します。TextBox をひとつ置き、IME を全角カナに設定し ON にします。
    さらに上記の添付プロパティを設定します。

    <Window x:Class="WpfApplication1.MainWindow"
    		xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    		xmlns:local="clr-namespace:WpfApplication1"
    		Title="MainWindow Height="150" Width="300">
    	<Grid>
    		<TextBox Name="textBox1" Height="23" Width="150" 
    				 HorizontalAlignment="Center" VerticalAlignment="Center"
    				 InputMethod.PreferredImeState="On"
    				 InputMethod.PreferredImeConversionMode="FullShape,Katakana"
    				 local:TextBoxBehaviors.IsKatakana="True" />
    	</Grid>
    </Window>
    

    アプリケーションを起動しキーボードから入力するとこちらの想定通りの動作をしますが、仮に「アイ」と打ち込んで、Enterキーで確定し、引き続き「アイ」と打ち込んでスペースキーで IME の変換候補を表示すると、以下のエラーが発生します。
     

    FatalExecutionEngineError が検出されました。 Message: ランタイムの重大なエラーが発生しました。エラーのアドレスは 0x58e29ddd、スレッド 0x1c60 です。エラー コードは 0x80131623 です。これは CLR のバグであるか、またはユーザー コードのアンセーフまたは確認不可能な部分にバグがある可能性があります。このバグの一般的な原因には、スタックが壊れる可能性のある COM-interop または PInvoke のユーザー マーシャリング エラーが含まれています。


    どうも動きを見ていると、OnTextKanaChanged が実行されて TextBox の文字列を変換した後に IME が起動し、変換する文字列が存在しないのでエラーが発生しているような感じです。この辺りの問題について、何か情報をお持ちの方はおられますでしょうか?

    ちなみに添付ビヘイビアの Replace.Replace メソッド内ではラムダ式を使ってますが、MatchEvaluator デリゲートを使うよう変更しても現象は変わりません。

    最後ですが、こちらの環境は、XP/SP3・VisualStudio 2010・Microsoft Office IME 2010 です。


    ひらぽん http://d.hatena.ne.jp/hilapon/
    • 編集済み ひらぽんModerator 2011年1月8日 7:42 編集して投稿したらレイアウトが崩れたので修正して投稿
    2011年1月8日 7:36
    モデレータ

回答