7

編集可能なコンテンツを持つコードを使用して GUI を構築しています。ユーザーが静的ディスプレイをクリックすると、コントロールが編集可能なコントロールに切り替わります。場合によっては、表示コントロール (例: ) がやLabelなどのコントロールのグループに置き換えられます。ComboBoxTextBox

インターフェイスをエディターからそのアイテムの表示表現に戻すために、編集可能なコントロールのグループからフォーカスが失われたことを検出したいと考えています。

たとえば、次のようなツリーに GUI があり、Panel1(Panel2(Button1, Button2), Button3)からフォーカスが失われたことを検出したいとし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

がクリックされた後に がクリックされると、panel2.LostFocusイベントがトリガーされます。これは、フォーカスが から に移動したためです。ただし、フォーカスが失われていないにもかかわらず、クリックされた後にクリックされた場合にもトリガーされます。button3button2panel1button3button2button1panel2

WPFのフォーカスに関するMSDNのドキュメントを読んで、追加しようとしました:

Input.FocusManager.SetIsFocusScope(panel2, true)

しかし、これは実際に問題を悪化させました!現在、イベントは、実際にフォーカスを失ったときではなく、ある子から別のpanel2.LostFocus子にフォーカスが移動したときにのみトリガーされます。panel2panel2

望ましい効果を得るにはどうすればよいですか?

4

1 に答える 1

7

Twitter のIan Voyceのおかげで、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
于 2012-11-24T00:50:06.967 に答える