2016-11-10 4 views
2

私はWPF TextBoxコントロールを派生し、入力として米国の通貨値のみを受け付けるコントロールを作成しています。私はこれが前に行われていて、私が使うことができる既存の図書館があることを知っていますが、これは既存の図書館管理の1つを使用しようとして失敗したことから生まれた、 。WPFコントロールを取得する場合、コントロールのイベントハンドラがイベントを最初に処理することを保証できますか?

これは、米国通貨フォーマット(オプションの先行通貨記号、小数、オプションのグループセパレータ、オプションの小数コンポーネント)に適合しないテキストをテキストボックスが受け入れることを防止しようとしています。私はPreviewTextInputイベントがあることを知っています。私は、多くの情報源から、このイベントを簡単に処理し、不要な入力を拒否するように提案しました。(コピー/ペーストテキスト、更新されたデータバインディング、デザインタイムのXAML値など)を指定します。

私はこのアプローチが常に機能しているかどうか疑問に思っています。 the order that event handlers are called is not guaranteedがあると、コントロールのイベントハンドラが最初に呼び出されたことをどのように知ることができますか?言い換えれば、誰かのイベントハンドラが最初に実行されず、私が禁止しようとしているフォーマットを許可する値で他の何かを実行してからe.Handled = trueを設定する方法を知るにはどうすればよいですか? OnPreviewTextInputメソッドはどうですか?私はそれが同様の懸念に苦しんでいると信じていますか?

+0

カスタムTextBoxを作成して使用してからPreviewTextInputを作成すると、これは延長しているTextBoxの前に実行されます。私はPreviewTextInputの前にプレビューキーを実行して、それを処理することができます。 – adminSoftDK

答えて

0

あなたがイベントハンドラを登録した方法によって順序付けられていることを指摘しています。実行時にリフレクションを使用してハンドラの順序を変更すると、予想どおりに動作する可能性があります。あなたが上で言ったように。ここ

が、私は誰かが

を作成した場合でも、

ANDIは

public class CustomBox : TextBox 
{ 
    public CustomBox() 
    { 
     this.PreviewTextInput += CustomBox_TextChanged; 
     this.PreviewTextInput += CustomBox_PreviewTextInput; 
    } 

    protected override void OnInitialized(EventArgs e) 
    { 
     base.OnInitialized(e); 

     foreach (var item in typeof(CustomBox).GetRuntimeMethods().ToList()) 
     { 
      var a = item.GetCustomAttributes(); 

      // unsubscribe 
      foreach (var i in a) 
      { 
       if (i.GetType() == typeof(CustomAttribute)) 
       { 
        if (((CustomAttribute)i).Value > 0) 
        { 
         RemoveEvent(((CustomAttribute)i).EventName, item.Name); 
        } 
       } 
      } 
     } 
     // subscribe according to your order 
     var methods = typeof(CustomBox).GetRuntimeMethods() 
        .Where(m => m.GetCustomAttributes(typeof(CustomAttribute), false).Length > 0) 
        .ToList(); 

     foreach (var item in methods.OrderBy(m => ((CustomAttribute)m.GetCustomAttribute(typeof(CustomAttribute))).Value)) 
     { 
      AddEvent(((CustomAttribute)item.GetCustomAttribute(typeof(CustomAttribute))).EventName, item.Name); 
     } 

    } 
    private void RemoveEvent(string eventName, string methodName) 
    { 
     EventInfo ev = this.GetType().GetEvent(eventName); 
     Type tDelegate = ev.EventHandlerType; 
     MethodInfo miHandler = typeof(CustomBox).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); 
     Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler); 
     ev.RemoveEventHandler(this, d); 
    } 

    private void AddEvent(string eventName,string methodName) 
    { 
     EventInfo ev = this.GetType().GetEvent(eventName); 
     Type tDelegate = ev.EventHandlerType; 
     MethodInfo miHandler = typeof(CustomBox).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); 
     Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler); 
     ev.AddEventHandler(this,d); 
    } 

    [CustomAttribute(EventName = "PreviewTextInput",Value = 2)] 
    private void CustomBox_TextChanged(object sender, TextCompositionEventArgs e) 
    { 
     this.Text = e.Text; 
     e.Handled = true; 
    } 

    [CustomAttribute(EventName = "PreviewTextInput", Value = 1)] 
    private void CustomBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     if (e.Text.Contains("e")) 
     { 
      e.Handled = true; 
     } 
     else e.Handled = false; 
    } 
} 

上のTextBoxから延長カスタムボックスを作成した属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class CustomAttribute : Attribute 
{ 
    private int _value; 

    public int Value 
    { 
     get { return _value; } 
     set { _value = value; } 
    } 

    private string _eventName; 

    public string EventName 
    { 
     get { return _eventName; } 
     set { _eventName = value; } 
    } 


    public CustomAttribute() 
    { 

    } 
} 
を定義し

this.PreviewTextInput + = CustomBox_TextChanged。 テキストボックスのテキストを操作して不本意なテキストに変更し、別のイベントをe.handle = trueでブロックするハンドラ。

this.PreviewTextInput + = CustomBox_PreviewTextInput; Reflectionは、定義した方法に従って注文を変更します。

関連する問題