2012-11-23 2 views
6

Ich baue eine GUI mit Code, der bearbeitbare Inhalte hat. Wenn der Benutzer auf die statische Anzeige klickt, wird das Steuerelement gegen ein Steuerelement ausgetauscht, das die Bearbeitung ermöglicht. In einigen Fällen wird die Anzeigesteuerung (z. B. Label) für eine Gruppe von Steuerungen ausgetauscht, z. B. ComboBox und TextBox.Erkenne Fokus verloren von einer Gruppe von WPF-Steuerelementen

Ich möchte erkennen, wenn der Fokus aus meiner Gruppe von bearbeitbaren Steuerelementen verloren geht, um die Schnittstelle vom Editor auf die Anzeigedarstellung für dieses Element zurück zu schalten.

Zum Beispiel könnte ich eine GUI in einem Baum wie haben und ich möchte erkennen, wenn der Fokus verloren geht von Panel2. Ich habe versucht, die folgenden (F # -Code):

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 

Das panel2.LostFocus Ereignis ausgelöst wird, wenn button3 geklickt wird nach button2 geklickt worden war, wie erwartet, da der Fokus, wie aus panel1 zu button3 bewegt. Es wird jedoch auch ausgelöst, wenn button2 geklickt wird, nachdem button1 geklickt wurde, obwohl panel2 nie den Fokus verloren hat.

die MSDN-Dokumentation über Fokus in WPF Lesen habe ich versucht, und fügte hinzu:

Input.FocusManager.SetIsFocusScope(panel2, true) 

aber das machte tatsächlich das Problem noch schlimmer! Das Ereignis panel2.LostFocus wird jetzt nur ausgelöst, wenn der Fokus von einem Kind von panel2 auf ein anderes verschoben wird und nicht, wenn panel2 tatsächlich den Fokus verliert.

Wie soll ich den gewünschten Effekt erzielen?

Antwort

6

Dank Ian Voyce auf Twitter war ich in der Lage, die Funktionalität zu erhalten, die ich brauchte, unter Verwendung des IsKeyboardFocusWithinChanged Ereignisses. Hier ist eine Demo:

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