2010-10-17 12 views
2

我有一個包含CheckBox,TextBlock和TextBox的自定義數據模板的ListBox。通常,當你選擇一個ListBox中的一個項目時,底層的ListBoxItem實際上是焦點所在,因此它響應上下鍵。此外,如果CheckBox具有焦點,由於它不會對上下鍵執行任何操作,它只是高興地忽略它們,並且它們也由底層的ListBoxItem處理。迄今爲止都是很好的。使WPF文本框或其他可調焦控件對某些按鍵(例如傳遞,不能吞下)是透明的

但是,TextBox對於向上和向下鍵具有其自己的處理規則,命名上移或下移文本中的一行,這不適用於此,因爲在這種情況下它是單行(它是一個數字實際上。)因此,如果TextBox具有焦點,則向上和向下鍵會中斷列表框的選擇導航,也不會真正幫助編輯。

現在,雖然我可以處理PreviewKeyDownEvent(我在下面做,但出於不同的原因)並根據按下的鍵手動處理行爲,但這是一個非常具體的解決方案,需要控件瞭解其容器的行爲。

在一個完美的世界裏(和僞代碼),我只想說MyTextBox.KeysToIgnore(上,下)或類似的東西,讓它做到這一點...忽略這些鍵,就好像它不是即使在那裏。 (同樣,無法下嚥,卻忽略了讓他們通過。)

但在此之前,這裏是我想出的,這似乎是工作,但只是看起來那麼「哈克」我...

private void PreviewKeyDownHandler(object sender, KeyEventArgs e) { 

    switch (e.Key){ 
     case Key.Up: 
     case Key.Down: 
     case Key.OtherKeyToIgnore 
     case Key.AndAnother 

      e.Handled = true; 

      FrameworkElement target = VisualTreeHelper.GetParent(
       e.Source as DependencyObject) as FrameworkElement; 

      target.RaiseEvent(
       new KeyEventArgs(
        e.KeyboardDevice, 
        PresentationSource.FromVisual(target), 
        0, 
        e.Key 
       ){ 
        RoutedEvent=Keyboard.KeyDownEvent 
       } 
      ); 
      break; 

    } 

} 

這也有不發送PreviewKeyDown事件到目標的負面影響。現在我可以解決這個問題,通過先發送該事件,然後在發送實際的KeyDown消息之前查看e.Handled,這很有道理,但之後我用PreviewKeyUp和KeyUp事件觸發另一個牆,因爲設置了e在上面的處理中,我從來沒有得到真正的'關鍵'事件來知道什麼時候發送假的。另外,我非常確定我也會打破PreviewKeyxxx消息的方向,因爲它們會從常規非預覽版本的相反方向冒泡。 (也許這是內部處理,但我不這麼認爲。)

就像我說的...哈克,哈克,哈克!

但它確實有效,所以就是這樣。我可以通過附加行爲來實現這一點,這就是爲什麼我走這條路。 (在附加的行爲實現中,它不是一個case語句,而是一個針對我在XAML中指定的密鑰集合的檢查。)我只是不喜歡丟失所有我想要的其他行爲的想法。

再說一遍,我只想說'嘿TextBox ...當你看到上或下鍵被按下,STFU雅b * stard !!'並以其他方式使其透明。

想到任何人?

回答

1

男人......甚至沒有一個評論,更let論在近一個月的答案!哦,好吧......我想我上面的'hacky'解決方案是這樣做的,所以我將其標記爲答案。

1

Yeh,TextBox的關鍵事件處理肯定會讓你頭疼。 問題在於無法確定通過EventManager.RegisterClassEventHandler註冊的回調的調用順序。即你的回調調用未處理的事件,然後事件處理,這就是它... 我找到了一種方法來通過繼承TextBox並在構造函數中調用「AddEventHandler(KeyDownEvent,callback,true)」來「處理」關鍵事件。然後根據情況設置e.Handled = false。似乎在事件由TextBox處理之後調用回調被調用。 每個TextBox實例都有一個委託實例,而不是每個類都有一個委託實例,但我看不到任何其他解決方法。

+0

你能提供樣本代碼嗎?我沒有真正遵循你在這裏所說的話。 (我想我是這樣做的,但我不是100%確定的,因爲我不知道你在調用哪個對象'AddEventHandler',因此需要三個這樣的參數。)再次說明,代碼在這裏會有很長的路要走。你能編輯你的答案並把它們放在那裏嗎?如果是這樣,它做我需要的,我會改變你的接受答案。謝謝! – MarqueIV 2010-12-09 07:13:53

+0

對不起,最近我很少訪問網站。我進入了情況,文本框位於模態窗口中,並且輸入綁定在「Enter」鍵上以接受對話。不管AcceptsReturn屬性如何,TextBox都在吃關鍵輸入。這是解決方法,是用於: – 2011-11-29 09:22:41

+0

公共類TextBox2中:文本框 { 私人無效的onkeydown(對象發件人,KeyEventArgs E) { 如果(e.Handled) 開關(e.Key) { 情況Key.Return : if(!AcceptsReturn)e.Handled = false; 休息; case Key.Tab: if(!AcceptsTab)e.Handled = false; 休息; } } public TextBox2() { AddHandler(KeyDownEvent,new KeyEventHandler(OnKeyDown),true); } } – 2011-11-29 09:24:54

相關問題