2017-11-22 11 views
0

自分自身をコーナーに描いた可能性があります。私は静的イベントを使用してフォーカスがあるときにキーをテキストボックスに渡すカスタムタッチキーボードユーザーコントロールを持っています。私はすべてのテキストボックスのための依存性のプロパティを作成しようとしている私のタッチキーボードイベントハンドラにフォーカスしているときに、彼らがフォーカスを失うときに退会を予約する。依存関係プロパティを使用した静的イベントハンドラコールバックへのTextBoxオブジェクト参照の割り当て

私の現在の問題は、PropertyChangedCallbackIsTouchKeyboardTargetChangedは決して発火しないということです。私はこれがXAMLで設定されているため、決して "変更しない"ためです。

これまでのところ私が見つけた他の回答は、私のパターンにはあまり適用されていません。私はこれが正しいことだと確信していませんが、これがうまくいくと私にとっては非常に便利です。私は、MahAppsをTextBoxHelperで設定した例に従っています。

誰かがPropertyChangedCallbackの問題を解決するのに役立つ人がいる場合や、すべてのテキストボックスでフォーカスイベントが発生したときに、静的イベントの購読/購読を解除する方法を知っている方がいらっしゃいましたら、

CS

public class TouchTextBoxHelper : DependencyObject 
{ 
    public static readonly DependencyProperty IsTouchKeyboardTargetProperty = DependencyProperty.Register("IsTouchKeyboardTarget", typeof(bool), typeof(TouchTextBoxHelper), new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged)); 


    [AttachedPropertyBrowsableForType(typeof(TextBox))] 
    public static bool GetIsTouchKeyboardTargetEnabled(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(IsTouchKeyboardTargetProperty); 
    } 

    [AttachedPropertyBrowsableForType(typeof(TextBox))] 
    public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value) 
    { 
     obj.SetValue(IsTouchKeyboardTargetProperty, value); 
    } 

    private static void IsTouchKeyboardTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var tb = d as TextBox; 
     if (null == tb) 
     { 
      throw new InvalidOperationException("The property 'IsTouchKeyboardTarget' may only be set on TextBox elements."); 
     } 

     if (e.OldValue != e.NewValue) 
     { 
      //tb.SetValue(SpellCheck.IsEnabledProperty, (bool)e.NewValue); 
      if ((bool)e.NewValue) 
      { 
       tb.GotFocus += TextBoxBaseGotFocus; 
       tb.LostFocus += TextBoxBaseLostFocus; 
      } 
      else 
      { 
       tb.GotFocus -= TextBoxBaseGotFocus; 
       tb.LostFocus -= TextBoxBaseLostFocus; 
      } 
     } 
    } 

    private static void TextBoxBaseGotFocus(object sender, RoutedEventArgs e) 
    { 
     TouchTextBoxEvents.tb = sender as TextBox; 
     StaticEvents.OnShowTouchKeyboard(sender, e); 
     StaticEvents.TouchKeyboardKeyTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch; 
     StaticEvents.TouchKeyboardSpaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch; 
     StaticEvents.TouchKeyboardBackspaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch; 
    } 

    private static void TextBoxBaseLostFocus(object sender, RoutedEventArgs e) 
    { 
     StaticEvents.OnHideTouchKeyboard(sender, e); 
     StaticEvents.TouchKeyboardKeyTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch; 
     StaticEvents.TouchKeyboardSpaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch; 
     StaticEvents.TouchKeyboardBackspaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch; 
    } 
} 

public class TouchTextBoxEvents 
{ 
    public static TextBox tb = null; 
    public static void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e) 
    { 
     int i = tb.CaretIndex; 
     string t = (sender as Button).Content.ToString(); 
     tb.Text = tb.Text.Insert(tb.CaretIndex, t); 
     tb.CaretIndex = i + 1; 
    } 

    public static void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e) 
    { 
     int i = tb.CaretIndex; 
     if (tb.CaretIndex == 0) return; 
     tb.Text = tb.Text.Remove(tb.CaretIndex - 1, 1); 
     tb.CaretIndex = i - 1; 
    } 

    public static void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e) 
    { 
     int i = tb.CaretIndex; 
     tb.Text = tb.Text.Insert(tb.CaretIndex, " "); 
     tb.CaretIndex = i + 1; 
    } 
} 

編集:

[AttachedPropertyBrowsableForType(typeof(TextBox))] 
    public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value) 
    { 
     obj.SetValue(IsTouchKeyboardTargetProperty, value); 
     TextBox tb = obj as TextBox; 
     if (tb == null) return; 
     if (value) 
     { 

      tb.GotFocus += TextBoxBaseGotFocus; 
      tb.LostFocus += TextBoxBaseLostFocus; 
     } 
     else 
     { 
      tb.GotFocus -= TextBoxBaseGotFocus; 
      tb.LostFocus -= TextBoxBaseLostFocus; 
     } 
    } 

EDIT2:

がでPropertyChangedCallbackロジックを置く

それは私がしなければならなかったすべては私のセッター更新した判明セッターはちょうど悪いです。幸いにも、Clemensは、Registerの代わりにRegisterAttachedを使用するためのアドバイスを提供しました。これにより、DependencyObjectから派生する必要がなくなり、PropertyChangedCallbackが発砲しないという問題が解決されました。

+0

これが添付プロパティであると思われる場合は、「Register」ではなく「RegisterAttached」を使用する必要があります。 TouchTextBoxHelperはDependencyObjectから派生する必要はないことにも注意してください。 – Clemens

+1

ありがとうございました!これはすべての私の問題を修正しました。私はあなたが回答者とすべての人を与えることができるように答えに入れておきたがっています。 – Iridium237

答えて

1

Registerの代わりにDependencyProperty.RegisterAttachedを呼び出して、添付プロパティを登録する必要があります。 DependencyObjectから宣言クラスを派生させる必要もありません。

public class TouchTextBoxHelper 
{ 
    public static readonly DependencyProperty IsTouchKeyboardTargetProperty = 
     DependencyProperty.RegisterAttached(
      "IsTouchKeyboardTarget", 
      typeof(bool), 
      typeof(TouchTextBoxHelper), 
      new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged)); 

    ... 
} 
関連する問題