私は次の誤解に直面しました。MouseButtonEventArgs.MouseDevice.DirectlyOver誤解
プリアンブル:RadioButtons
と(コンボボックスのように)Popup
に基づいて、ドロップダウンを使用し、いくつかのコントロール:
Iは、次の必須のUI部品とアプリケーションWPF有します。いくつかのロジックに応じてすべてのラジオボタンのフックPreviewMouseDown
フックといくつかの計算を行います。次のシナリオでは 、
- ユーザーは、ポップアップを開きます(何かを選択しないでください、ポップアップがちょうどオープン滞在)
- 期待通りのRadioButton
PreviewMouseDown
上のユーザーのクリックでラジオボタンのために解雇されることはありません(理由Popup
feature)。
PreviewMouseDown
RadioButton
にもかかわらず、私の目的は発砲しています。を解決する
試み:
高速かつ汚いソリューションです:必要に応じてソースとしてラジオボタン使用して、Popup
ためPreviewMouseDown
と再火新しいソースとPreviewMouseDown
イベントをフック。新しいソースはMouseButtonEventArgs.MouseDevice.DirectlyOver
で取得できます。
private static void GrantedPopupPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var popup = sender as Popup;
if(popup == null)
return;
var realSource = e.MouseDevice.DirectlyOver as FrameworkElement;
if(realSource == null || !realSource.IsLoaded)
return;
var parent = LayoutTreeHelper.GetParent<Popup>(realSource);
if(parent == null || !Equals(parent, popup))
{
e.Handled = true;
var args = new MouseButtonEventArgs(e.MouseDevice,
e.Timestamp,
e.ChangedButton)
{
RoutedEvent = UIElement.PreviewMouseDownEvent,
Source = e.MouseDevice.DirectlyOver,
};
realSource.RaiseEvent(args);
}
}
この作品をうまくを私はBehavior
を介して直接Popup.PreviewMouseDown
にそのハンドラを装着していたときに:コードの次の部分は、(Popup
が外側クリック用PreviewMouseDown
を「食べる」場合にのみ、イベントは、解雇し直される)ことをやります
EventManager.RegisterClassHandler(
typeof (Popup),
PreviewMouseDownEvent,
new MouseButtonEventHandler(GrantedPopupPreviewMouseDown));
0123:私はEventManager.RegisterClassHandler
を経由して1を装着していた場合(PreviewMouseDown
は、ラジオボタンのために解雇されていない)動作しません(その目的は、これらのラジオボタンでページ上occureことができるすべてのPopup
に行動を取り付ける避けるためです) デバッガは、(上記のコードを参照)がPopup
ではなく、Radiobutton
ではないことを示しました(ハンドラをBehavior
経由で接続したときと同じです)。
質問:
どのように、なぜEventHandlerは2つの異なる方法で接続されている場合MouseButtonEventArgs
は、同じアクションのために異なることができますか?
誰かがこの動作を説明できますか?
ありがとうございます。
は私たちのためにそのためのXAMLで、最小限の再現可能なテストケースがあります遊ぶ?プレビューがWPFのコンテキストで何を意味するのか混乱するかもしれません。プレビューとして*イベントはイベントをトンネリングしているので、デフォルトではMouseDownイベントを使用してビジュアルツリーをバブリングすることができます – Samuel
ポップアップとラジオボタンのXAMLを投稿できますか?サムエルの言ったように、これはトンネリングとバブリングの出来事の問題です。ポップアップでイベントが処理される前に、Radiobuttonに到達することもできます。 –
暗闇の中でちょうど刺すが、この作品のようなものだろうか?ポップアップのMouseDownイベントハンドラ=> popup.Close(); radiobuttonのMouseUpイベントハンドラ=>あなたのことをやってください。最初のMouseDownアクションはポップアップを閉じ、2番目のMouseUpアクションはラジオボタンでキャプチャされます。 – Marko