在其他地方捕获事件而不是在后面的代码中

时间:2014-02-28 15:06:42

标签: c# wpf

我的应用程序中有一些Window,它们的格式是封装在<ContentPresenter>中。在这种风格中,我构建了一个模板,其中我有一些自定义userControls,如自定义titleBar和某个地方,ContentPresenter包含任何窗口的内容。目标是提取每个窗口所需的xaml并放入样式中的模板。 这正是wpf的用途。

然后,当用户在任何地方点击其内容时,我希望从这些窗口的所有中引发一个事件。所以我添加了风格:

<ContentPresenter PreviewMouseDown="somethingMouseDowned" />

请注意,首先,我将此应用于窗口内的grisd,并且在后面的代码(xaml.cs)中,我处理了事件,做了我想做的事情,一切都很好。

但我希望事件处理在窗口中不可见。这就是为什么我把PreviewMouseDown放在样式中。我也不希望我的代码中有任何处理代码。

问题在于我不知道如何在其他地方处理事件而不是在后面的代码中处理事件。我需要替代品。

提前致谢

3 个答案:

答案 0 :(得分:1)

您还可以使用AttachedProperty(EventToCommand)并将此事件绑定到viewmodel中的命令(ICommand)。 这是代码:

 public static class ContenPreviewMouseDownCommandBinding
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof (ICommand), typeof (ContenPreviewMouseDownCommandBinding), 
            new PropertyMetadata(default(ICommand), HandleCommandChanged));

        private static void HandleCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var contentPresenter = d as ContentPresenter;
            if(contentPresenter!=null)
            {
                contentPresenter.PreviewMouseDown += new MouseButtonEventHandler(contentPresenter_PreviewMouseDown);
            }
        }

        static void contentPresenter_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var contentPresenter = sender as ContentPresenter;
            if(contentPresenter!=null)
            {
                var command = GetCommand(contentPresenter);
                command.Execute(e);
            }            
        }

        public static void SetCommand(ContentPresenter element, ICommand value)
        {
            element.SetValue(CommandProperty, value);
        }

        public static ICommand GetCommand(ContentPresenter element)
        {
            return (ICommand) element.GetValue(CommandProperty);
        }
    }
在XAML中

   <ContentPresenter CommandBindings:ContenPreviewMouseDownCommandBinding.Command="{Binding Path=AnyCommandInScopeOfDataContext}">

                </ContentPresenter>

答案 1 :(得分:0)

在某种程度上,您将不得不在代码隐藏中使用一些代码来处理该事件。但是,为了最大限度地减少代码隐藏中的代码量,您可以使用MVP pattern并将所有事件处理封装到演示者类中,或者您可以使用其他一些工具集,例如Galasoft MVVMLight Messenger所描述的在此SO discussion

答案 2 :(得分:0)

如果你在其他类中有静态事件处理程序,请尝试使用
{x:Static anotherClass.somethingMouseDowned}