WPF:如何为内容更改创建路由事件?
WPF: How to created a routed event for content changed?
我有一个相框。我用这条线切换页面:
FrameName.Content = new PageName();
我希望故事板在页面更改时开始,我想在 XAML 中而不是在代码隐藏中进行。我试过以下代码:
<Frame.Triggers>
<EventTrigger RoutedEvent="ContentChanged">
<BeginStoryboard Storyboard="{StaticResource storyboardName}" />
</EventTrigger>
</Frame.Triggers>
经过一番搜索,我意识到没有这种性质的内置路由事件。第一个答案 here 建议
The most dynamic approach is to simply derive your own label control that provides a ContentChanged event.
我已经尝试实现这个答案中的代码:
using System.Windows;
using System.Windows.Controls;
namespace ContentChangedTest
{
class MyFrame : Frame
{
public event DependencyPropertyChangedEventHandler ContentChanged;
static MyFrame()
{
ContentProperty.OverrideMetadata(typeof(MyFrame), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnContentChanged)));
}
private static void OnContentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
MyFrame frame = dp as MyFrame;
if (frame.ContentChanged != null)
{
DependencyPropertyChangedEventArgs args = new DependencyPropertyChangedEventArgs(ContentProperty, e.OldValue, e.NewValue);
frame.ContentChanged(frame, args);
}
}
}
}
在XAML我使用它是这样的:
<local:MyFrame ContentChanged="MyFrame_ContentChanged" />
问题是我最终需要在代码隐藏中创建一个事件处理程序 MyFrame_ContentChanged
。有没有办法在纯 XAML 中做到这一点?例如 - 我可以将 ContentChanged
依赖项 属性 转换为某种路由事件吗?
为了在 EventTriggers
中使用事件,它们应该是路由事件。路由事件的定义方式类似于依赖属性。这是有关如何开始的快速教程:How to: Create a Custom Routed Event.
这是从 ContentControl
派生的 class 的示例,它定义了 ContentChanged
事件:
public class MyContentControl : ContentControl
{
public static readonly RoutedEvent ContentChangedEvent
= EventManager.RegisterRoutedEvent(
"ContentChanged",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyContentControl));
public event RoutedEventHandler ContentChanged
{
add { AddHandler(ContentChangedEvent, value); }
remove { RemoveHandler(ContentChangedEvent, value); }
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
RaiseEvent(new RoutedEventArgs(ContentChangedEvent, this));
}
}
我还不确定为什么,但在测试此行时在 Style
中工作,但在直接用于控件的触发器集合中时抛出异常:
<EventTrigger RoutedEvent="ContentChanged">...</EventTrigger>
为了让它在这种情况下工作,我必须指定一个完全限定的事件路径:
<EventTrigger RoutedEvent="local:MyContentControl.ContentChanged">...</EventTrigger>
我有一个相框。我用这条线切换页面:
FrameName.Content = new PageName();
我希望故事板在页面更改时开始,我想在 XAML 中而不是在代码隐藏中进行。我试过以下代码:
<Frame.Triggers>
<EventTrigger RoutedEvent="ContentChanged">
<BeginStoryboard Storyboard="{StaticResource storyboardName}" />
</EventTrigger>
</Frame.Triggers>
经过一番搜索,我意识到没有这种性质的内置路由事件。第一个答案 here 建议
The most dynamic approach is to simply derive your own
labelcontrol that provides a ContentChanged event.
我已经尝试实现这个答案中的代码:
using System.Windows;
using System.Windows.Controls;
namespace ContentChangedTest
{
class MyFrame : Frame
{
public event DependencyPropertyChangedEventHandler ContentChanged;
static MyFrame()
{
ContentProperty.OverrideMetadata(typeof(MyFrame), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnContentChanged)));
}
private static void OnContentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
MyFrame frame = dp as MyFrame;
if (frame.ContentChanged != null)
{
DependencyPropertyChangedEventArgs args = new DependencyPropertyChangedEventArgs(ContentProperty, e.OldValue, e.NewValue);
frame.ContentChanged(frame, args);
}
}
}
}
在XAML我使用它是这样的:
<local:MyFrame ContentChanged="MyFrame_ContentChanged" />
问题是我最终需要在代码隐藏中创建一个事件处理程序 MyFrame_ContentChanged
。有没有办法在纯 XAML 中做到这一点?例如 - 我可以将 ContentChanged
依赖项 属性 转换为某种路由事件吗?
为了在 EventTriggers
中使用事件,它们应该是路由事件。路由事件的定义方式类似于依赖属性。这是有关如何开始的快速教程:How to: Create a Custom Routed Event.
这是从 ContentControl
派生的 class 的示例,它定义了 ContentChanged
事件:
public class MyContentControl : ContentControl
{
public static readonly RoutedEvent ContentChangedEvent
= EventManager.RegisterRoutedEvent(
"ContentChanged",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyContentControl));
public event RoutedEventHandler ContentChanged
{
add { AddHandler(ContentChangedEvent, value); }
remove { RemoveHandler(ContentChangedEvent, value); }
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
RaiseEvent(new RoutedEventArgs(ContentChangedEvent, this));
}
}
我还不确定为什么,但在测试此行时在 Style
中工作,但在直接用于控件的触发器集合中时抛出异常:
<EventTrigger RoutedEvent="ContentChanged">...</EventTrigger>
为了让它在这种情况下工作,我必须指定一个完全限定的事件路径:
<EventTrigger RoutedEvent="local:MyContentControl.ContentChanged">...</EventTrigger>