在WPF中将事件从样式传播到MainWindow
本文关键字:样式 传播 MainWindow 事件 WPF | 更新日期: 2023-09-27 18:30:00
我在一个单独的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
。
我找到了这篇文章,但它看起来并不是完全一样的情况,所以我没有找到任何不同的文章或任何答案,我都会非常感激。
在这种情况下使用EventSetter
的做法不是最好的。原因如下:
- 他被绑定到BAML文件,该文件应该是事件处理程序
因为它仅限于事件的全局函数,所以他只是在xaml.cs
文件中查找事件处理程序。也正因为如此,从MSDN
:
不能在主题资源字典中包含的样式中使用事件设置器。
- 不能在触发器中设置
EventSetter
引用自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>
更多信息,可以在这里找到:
在MVVM 的XAML中使用EventTrigger
将WPF事件绑定到MVVM Viewmodel命令