2012-11-23 54 views
6

我使用具有可編輯內容的代碼構建GUI。當用戶點擊靜態顯示時,控件被換出一個允許編輯的控件。在某些情況下,顯示控件(例如Label)會換出一組控件,如ComboBoxTextBox檢測從一組WPF控件丟失的焦點

我想要檢測何時從我的可編輯控件組中丟失焦點,以便將界面從編輯器切換回該項目的顯示錶示。

例如,我可能在像Panel1(Panel2(Button1, Button2), Button3)這樣的樹中有一個GUI,並且我想要檢測何時從Panel2丟失焦點。我嘗試以下(F#代碼):

open System.Windows 

let button1 = Controls.Button(Content="1") 
let button2 = Controls.Button(Content="2") 
let button3 = Controls.Button(Content="3") 

[<System.STAThreadAttribute>] 
do 
    let panel1 = Controls.StackPanel() 
    let panel2 = Controls.StackPanel() 
    panel2.Children.Add button1 |> ignore 
    panel2.Children.Add button2 |> ignore 
    panel1.Children.Add panel2 |> ignore 
    panel1.Children.Add button3 |> ignore 
    panel2.LostFocus.Add(fun _ -> 
    printfn "Panel2 lost focus") 
    Application().Run(Window(Content=panel1)) 
    |> ignore 

當點擊button3button2已經被點擊後,如預期,則觸發事件panel2.LostFocus,因爲搬出panel1button3焦點。但是,button2點擊button1被點擊後也被觸發,即使panel2從未失去焦點。

閱讀有關重點MSDN文檔中的WPF我嘗試添加:

Input.FocusManager.SetIsFocusScope(panel2, true) 

但是這實際上使問題變得更糟!現在panel2.LostFocus事件僅在從panel2的一個孩子轉移到另一個孩子時才被觸發,而當panel2實際上失去焦點時纔會觸發該事件。

我應該如何獲得所需的效果?

回答

6

感謝Ian Voyce在Twitter上,我能夠使用IsKeyboardFocusWithinChanged事件獲得我需要的功能。這裏有一個演示:

open System.Windows 

let Button x = 
    Controls.Button(Content=x, Width=64.0, Margin=Thickness 3.0) 

let Panel ctrls = 
    let panel = Controls.StackPanel() 
    for ctrl in ctrls do 
    panel.Children.Add ctrl 
    |> ignore 
    panel 

let label = Controls.Label(Content="Edit 12") 
let button1 = Button "1" 
let button2 = Button "2" 
let button3 = Button "3" 

let panel = Panel[button1; button2] 

[<System.STAThreadAttribute>] 
do 
    label.HorizontalContentAlignment <- HorizontalAlignment.Center 
    label.MouseLeftButtonDown.Add(fun _ -> 
    label.Content <- panel) 
    panel.IsKeyboardFocusWithinChanged.Add(fun e -> 
    if not(unbox e.NewValue) then 
     label.Content <- "Edit 12") 
    Application().Run(Window(Content=Panel[label :> UIElement; button3 :> UIElement])) 
    |> ignore