2012-11-23 13 views
6

Buduję GUI za pomocą kodu, który ma edytowalną zawartość. Kiedy użytkownik kliknie na wyświetlacz statyczny, sterowanie jest zamieniane na takie, które umożliwia edycję. W niektórych przypadkach kontrola wyświetlania (na przykład Label) jest zamieniana na grupę elementów sterujących, takich jak ComboBox i TextBox.Wykryj fokus utracony z grupy kontrolek WPF

Chcę wykryć, kiedy ostrość jest tracona z mojej grupy edytowalnych elementów sterujących, aby przełączyć interfejs z powrotem z edytora na reprezentację wyświetlania dla tego elementu.

Na przykład mogę mieć GUI w drzewie takim jak Panel1(Panel2(Button1, Button2), Button3) i chciałbym wykryć, kiedy utracono ostrość z Panel2. Próbowałem następujący kod (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 

Impreza panel2.LostFocus jest wyzwalany po kliknięciu button3 po button2 został kliknięty, zgodnie z oczekiwaniami, ponieważ ostrość jak przeniesiony z panel1 do button3. Jednak jest on również wywoływany po kliknięciu button2 po kliknięciu na button1, mimo że nigdy nie utracono ostrości.

Przeczytanie dokumentacji MSDN o ostrości w WPF próbowałem dodając:

Input.FocusManager.SetIsFocusScope(panel2, true) 

ale to rzeczywiście problem gorzej! Teraz zdarzenie panel2.LostFocus jest wyzwalane tylko wtedy, gdy przesunięcie fokusu od jednego dziecka z panel2 do innego, a nie gdy faktycznie straci fokus.

Jak uzyskać pożądany efekt?

Odpowiedz

6

Dzięki Ian Voyce na Twitterze mogłem uzyskać potrzebną funkcjonalność przy użyciu zdarzenia IsKeyboardFocusWithinChanged. Oto wersja demonstracyjna:

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 
Powiązane problemy