c# - WPF:如何为内容更改创建路由事件?

标签 c# wpf xaml eventtrigger routed-events

我有一个框架。我用这一行切换页面:

FrameName.Content = new PageName();

我希望在页面更改时开始 Storyboard,并且我想在 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 派生的类的示例,它定义了 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>

关于c# - WPF:如何为内容更改创建路由事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36384389/

相关文章:

wpf - 未定义的 CLR 命名空间

c# - 时间线中可调整大小的片段 : bind segment size to view model

wpf - 如何为特定数据类型的 ListBoxItems 应用样式 setter ?

c# - 将模型的另一个实例分配给 ViewModel

c# - 寻找解释设计模式的高质量视频

c# - 将 WebAPI HttpGet 方法参数重新组合到一个对象中

c# - OData 异常 : A recursive loop of complex types is not allowed

c# - 将 ObservableCollection<child> 传递给采用 ObservableCollection<parent> 的函数

c# - 使用 WPF 在虚拟化 TreeView 中选择一个节点

c# - 用等效字符串表示 Char