如何在UserControl上使用交互行为

时间:2014-07-02 09:18:14

标签: c# wpf xaml user-controls attachedbehaviors

我有以下具有附加行为的UserControl。目前,我必须选择一个DataGrid项目才能运行该行为。

只能在这里猜测,但它是可以理解的,因为这些容器不可调焦或者不应该注册键盘事件,所以它会转到下一个可用的孩子???

我可以将这个功能放在窗口上,但是这个UserControl可以与另一个UserControl交换出来,我更喜欢它不是躺在那里。 这只是我的应用程序中的一个独特案例,其中窗口上唯一的东西是DataGrid,我不一定要选择DataGrid项来开始行为。

我的问题是:是否可以使以下行为起作用?可以在UserControl,Grid或其他允许此操作的控件上使用。

<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>

以下是行为:

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); }
    }
}

1 个答案:

答案 0 :(得分:1)

到目前为止,我可以看到,如果您的问题是焦点

即使重点关注对照的孩子或他们的后代,您也可以利用Preview事件来接收事件

protected override void OnAttached()
{
    base.OnAttached();
    this.AssociatedObject.PreviewKeyDown += _KeyBoardBehaviorKeyDown;
}

protected override void OnDetaching()
{
    base.OnDetaching();
    this.AssociatedObject.PreviewKeyDown-= _KeyBoardBehaviorKeyDown;
}

我已将KeyDown更改为PreviewKeyDown

只要AssociatedObject关注它或其中的任何子项,

上述解决方案就会起作用。如果你期待全局控制它,那么你可能需要将事件附加到顶级元素,例如。 Window

所以为了做到这一点,你需要找到AssociatedObject的适当父级并将事件附加到同一个。

还要确保以下演员表有效

FindPopupObject as UserManagement.Controls.NonTopmostPopup;

可能是

FindPopupObject as Popup;