2

我在单独的 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)引发一个事件,但我不知道如何将此事件传播到MainWindow.

我找到了这篇文章,但它看起来并不像同样的情况,所以任何我没有找到的不同文章或任何答案我都会非常感激。

4

1 回答 1

2

在这种情况下使用的做法EventSetter,并不是最好的。这就是为什么:

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

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

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

  • EventSetter不能在Trigger中设置

引用自link

因为使用 EventSetter 连接事件处理程序是一个通过 IStyleConnector 接口探测的编译时功能,所以 XAML 编译器使用另一个名为 IComponentConnector 的接口来连接独立 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...
    }
}

更多信息可以在这里找到:

如何继承 WPF 样式中的按钮行为?

从用户控件退出应用程序

如何在没有数据绑定的情况下登录失败时清除 PasswordBox 的内容?

2 - Commands

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

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

在这种情况下,它们可以而且应该用于Styles, Templates, DataTemplates. 在风格上,您可以设置如下命令:

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

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

在 XAML 中为 MVVM 使用 EventTrigger

将 WPF 事件绑定到 MVVM Viewmodel 命令

于 2013-09-02T05:20:50.790 回答