Reputation: 2616
I have the following UserControl that has an attached behavior on it. At the moment I have to select one of the DataGrid items in order for it to run the behavior.
Only guessing here but it's kind of understandable because these containers are not focusable or are not supposed to register keyboard events, so it goes to the next child available???
I could place this functionality on the window however this UserControl can get swapped out with another UserControl and I prefer for it not be be lying around. This is just a unique case in my app where the only thing on the window is the DataGrid and I don't necessarily want to select a DataGrid item to begin the behavior.
My question is: Is it possible to get the following behavior to work? Either on the UserControl, Grid or maybe some other control that would permit this.
<UserControl x:Class="UserManagement.LaunchPad"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="clr-namespace:UserManagement.Helpers"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<i:Interaction.Behaviors>
<helpers:OpenPopupBehaviors FindPopupObject="{Binding ElementName=PopupFind}"
GotoPopupObject="{Binding ElementName=PopupGoto}" />
</i:Interaction.Behaviors>
<Grid>
<DockPanel>
<DataGrid />
</DockPanel>
<Popup Name="PopupGoto" />
<Popup Name="PopupFilter "/>
</Grid>
</UserControl>
Here is the behavior:
class OpenPopupBehaviors : Behavior<UserControl>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.KeyDown += _KeyBoardBehaviorKeyDown;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.KeyDown -= _KeyBoardBehaviorKeyDown;
}
void _KeyBoardBehaviorKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.F && (Keyboard.Modifiers & (ModifierKeys.Control)) == (ModifierKeys.Control))
{
var popup = FindPopupObject as UserManagement.Controls.NonTopmostPopup;
if (popup == null)
return;
popup.IsOpen = true;
}
if (e.Key == Key.G && (Keyboard.Modifiers & (ModifierKeys.Control)) == (ModifierKeys.Control))
{
var popup = GotoPopupObject as Popup;
if (popup == null)
return;
popup.IsOpen = true;
}
}
public static readonly DependencyProperty FindPopupObjectProperty =
DependencyProperty.RegisterAttached("FindPopupObject", typeof(object), typeof(OpenPopupBehaviors), new UIPropertyMetadata(null));
public object FindPopupObject
{
get { return (object)GetValue(FindPopupObjectProperty); }
set { SetValue(FindPopupObjectProperty, value); }
}
public static readonly DependencyProperty GotoPopupObjectProperty =
DependencyProperty.RegisterAttached("GotoPopupObject", typeof(object), typeof(OpenPopupBehaviors), new UIPropertyMetadata(null));
public object GotoPopupObject
{
get { return (object)GetValue(GotoPopupObjectProperty); }
set { SetValue(GotoPopupObjectProperty, value); }
}
}
Upvotes: 0
Views: 4234
Reputation: 13679
So far I can see is that the focus if your issue
you can make use of Preview
events to receive the events even if the focus is on control's child or their descendants
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PreviewKeyDown += _KeyBoardBehaviorKeyDown;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.PreviewKeyDown-= _KeyBoardBehaviorKeyDown;
}
I have changed KeyDown
to PreviewKeyDown
above solution will work as long as the AssociatedObject
have focus on it or any child within it. if you look forward to control it globally then perhaps you may need to attach the events to top level elements eg. Window
so in order to do that you need to find the appropriate parent of AssociatedObject
and attach the event to the same.
also make sure that the following cast is valid
FindPopupObject as UserManagement.Controls.NonTopmostPopup;
it could be
FindPopupObject as Popup;
Upvotes: 1