在WPF中将事件从样式传播到MainWindow

时间:2013-09-01 21:25:08

标签: c# wpf events eventsetter

我在单独的XAML CustomTabItem.xaml中有一个自定义样式,它会引发如下事件:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                x:Class="myProject.CustomTabItem">
    ...
    ...

    <MenuItem Header="One">
        <MenuItem.Style>
            <Style TargetType="{x:Type MenuItem}">
                <EventSetter Event="Click" Handler="ClickNewSpaceOne"/>
            </Style>
        </MenuItem.Style>
    </MenuItem>

    ...
    ...

</ResourceDictionary>

这很容易在我创建的名为CustomTabItem.xaml.cs的文件中引发事件:

namespace myProject
{
    partial class CustomTabItem
    {
        private void ClickNewSpaceOne(object sender, RoutedEventArgs e)
        {
            //do stuff here
        }
    }
}

这一切都很好,但我现在需要在MainWindow中引发一个事件(当然在事件处理程序ClickNewSpaceOne中),但我无法弄清楚如何将此事件传播到{{ 1}}。

我找到了this文章,但它看起来并不是同样的情况,所以我找不到任何不同的文章或任何我真正理解的答案。

1 个答案:

答案 0 :(得分:2)

在这种情况下使用EventSetter的做法,而不是最好的做法。这就是原因:

  • 他被绑定到BAML文件,该文件应该是事件处理程序

因为它仅限于事件的全局功能,他只是在xaml.cs文件中查看事件处理程序。另外,正因为如此,来自MSDN

  

事件设置器不能用于主题资源字典中包含的样式。

  • EventSetter无法在“触发器”
  • 中设置

引自link

  

因为使用EventSetter连接事件处理程序是一个编译时功能,它通过IStyleConnector接口检测,所以有另一个名为IComponentConnector的接口,XAML编译器使用该接口为独立的XAML元素连接事件处理程序。

What alternatives?

1 - Attached dependency property

使用附加的依赖项属性及其UIPropertyMetadata,您可以实现必要的逻辑。例如:

// GetValue
// SetValue

public static readonly DependencyProperty SampleProperty =
                                      DependencyProperty.RegisterAttached("Sample",
                                      typeof(bool),
                                      typeof(SampleClass),
                                      new UIPropertyMetadata(false, OnSample));

private static void OnSample(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue is bool && ((bool)e.NewValue) == true)
    {
        // do something...
    }
}

可在此处找到更多信息:

How to inherit Button behaviour in WPF style?

Quit application from a user Control

How to clear the contents of a PasswordBox when login fails without databinding?

2 - Commands

WPF中的命令非常强大。引自MSDN

  

第一个目的是将语义和调用命令的对象与执行命令的逻辑分开。这允许多个不同的源调用相同的命令逻辑,并允许为不同的目标定制命令逻辑。

在这种情况下,它们可以而且应该在StylesTemplatesDataTemplates中使用。在样式中,您可以设置如下命令:

<Setter Property="Command" 
        Value="{Binding DataContext.YourCommand,
                RelativeSource={Relative Source AncestorType={x:Type Control}}}">

此外,如果要引用该命令,可以将该命令声明为静态属性,然后可以使用Static扩展来引用它。

3 - Using EventTrigger with Interactivity

在这种情况下,命令由EventTrigger调用。例如:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseEnter" >
        <i:InvokeCommandAction Command="{Binding MyCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

更多信息,可以在这里建立:

Using EventTrigger in XAML for MVVM

Binding WPF events to MVVM Viewmodel commands