2013-02-12 85 views
0

我已經在每個單元格中創建了一個帶有可編輯文本塊的自定義網格控件。通過雙擊觸發編輯,如下所示:無法弄清楚爲什麼控件失去焦點

void TextBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
{ 
    if (e.ClickCount == 2) Edit(); 
} 

public void Edit() 
{ 
    TextBox.Text = TextBlock.Text; 
    TextBlock.Visibility = System.Windows.Visibility.Collapsed; 
    TextBox.Visibility = System.Windows.Visibility.Visible; 
    Dispatcher.BeginInvoke((ThreadStart)delegate 
    { 
     TextBox.Focus(); 
     TextBox.SelectAll(); 
    }); 
} 

該零件按預期工作。

我希望讓用戶能夠通過按Tab鍵前進或移動標籤返回來爲下一個單元格添加標籤。我說這是引發像這樣的事件:

void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) 
{ 
    if (e.Key == System.Windows.Input.Key.Tab) 
    { 
     e.Handled = true; 
     OnTab(System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftShift) || System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.RightShift)); 
    } 
} 

外網處理這一事件,並呼籲一個或下一個可編輯單元的Edit()方法。這與預期的幾乎一樣,只要我實際上沒有在文本框中輸入。出於某種原因,如果我輸入了任何內容,則LostFocus事件不僅會觸發當前單元格(預期在Edit()在文本框中調用Focus()之後),還會觸發下一個單元格。以下是LostFocus事件的代碼。 (雖然我敢肯定這是不相關的。)

void TextBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    bool TextChanged = TextBox.Text != TextBlock.Text; 
    TextBlock.Text = TextBox.Text; 
    TextBlock.Visibility = System.Windows.Visibility.Visible; 
    TextBox.Visibility = System.Windows.Visibility.Collapsed; 
    if (TextChanged) OnTextChanged(); 
} 

我可以建立某種形式的花哨的門拿到文本框忽略此事件,但我,爲什麼它甚至射擊更加好奇,或在至少我怎麼能找到答案。

謝謝。

編輯:

因此很明顯,即使有一些門,我還是大清洗。我添加了一個叫布爾和Editing改變了Edit()方法是這樣的工作:

public void Edit() 
{ 

    TextBox.Text = TextBlock.Text; 
    TextBlock.Visibility = System.Windows.Visibility.Collapsed; 
    TextBox.Visibility = System.Windows.Visibility.Visible; 

    Thread Task = new Thread(() => 
    { 
     Editing = true; 
     Dispatcher.BeginInvoke((ThreadStart)delegate 
     { 
      System.Windows.Input.Keyboard.Focus(TextBox); 
      TextBox.SelectAll(); 
      EditGate.Set(); 
     }); 
     EditGate.WaitOne(); 
     Editing = false; 
    }); 
    Task.Start(); 
} 

再變引發LostFocus處理程序:

void TextBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (Editing) return; 

    // ... Some more code. 
} 

不幸的是這也不起作用。事情最終會像這樣:

  1. 當前單元格:編輯開始了假
  2. 當前單元格:標籤事件觸發
  3. 下一小區:編輯()稱爲
  4. 下一小區:編輯設置爲True
  5. 下一小區:EditGate.WaitOne()稱爲
  6. 下一小區:Keyboard.Focus()稱爲
  7. 當前單元格:聚焦丟失(編輯還是假的)
  8. 下一小區:Textbox.SelectAll()稱爲
  9. 下一小區:EditGate.Set()稱爲
  10. 下一小區:編輯設置爲False
  11. 下一小區:聚焦丟失(編輯現在是假的)

我不確定爲什麼LostFocus事件會在之後發射。這幾乎就像它知道我在做什麼。:P

+0

是否有焦點調用線程和調用特定的原因是什麼? – 2013-02-12 03:10:01

+0

@ sa_ddam213 - 是的,因爲如果它沒有被調用,它什麼也不做。不知道爲什麼。 – 2013-02-12 03:14:11

回答

1

我認爲這可能是由於KeyboardFocus,在WPF中你可以設置「邏輯」的重點和KeyboardFocus它只是一個猜測,但是當你在文本框中鍵入的aquiring的KeyBoardFocus可能改變邏輯焦點的狀態。

對我來說測試有點困難,但嘗試在Edit()方法中設置鍵盤焦點並查看會發生什麼。

public void Edit() 
{ 
    TextBox.Text = TextBlock.Text; 
    TextBlock.Visibility = System.Windows.Visibility.Collapsed; 
    TextBox.Visibility = System.Windows.Visibility.Visible; 
    Dispatcher.BeginInvoke((ThreadStart)delegate 
    { 
     Keyboard.Focus(TextBox); 
     TextBox.SelectAll(); 
    }); 
} 

我一直有問題操縱WPF焦點從後面的代碼,我想它,因爲那不是怎麼它的設計工作,它可能是更好的使用XAML中觸發排序的焦點(如果可能)

也許FocusManager類或許能夠提供幫助,在這裏你可以添加刪除當前/下一個項目的重點處理,

FocusManager.RemoveLostFocusHandler(TextBox, TextBox_LostFocus); 
FocusManager.AddLostFocusHandler(TextBox, TextBox_LostFocus); 
+0

它沒有區別。 :(還是感謝我不知道Keyboard/Logical的概念,還有其他建議嗎? – 2013-02-12 02:58:05

+0

嗯..我會看看我是否可以模擬和複製,你只是使用標準的'DataGrid',而這個控件是隻是一個自定義的'DataGridColumn'? – 2013-02-12 03:07:38

+0

網格只是一個網格,單元格也是網格,只有一個單元格,每個單元格都有一個TextBlock和TextBox,但是TextBox是隱藏的。 – 2013-02-12 03:08:49

相關問題