【问题标题】:Trigger an EventTrigger by an AttachedEvent通过 AttachedEvent 触发 EventTrigger
【发布时间】:2013-05-20 09:12:47
【问题描述】:

我有一个自定义的Panel,它引发了一个在静态类中全局定义的RoutedEvent

 public class CompressItemsToFitStackPanel : StackPanel
 {
    protected override Size ArrangeOverride(Size arrangeSize)
    {        
        // some logic 
        // Raise Attached Event     
        CustomEventManager.RaiseArrangeEvent(this);
        return base.ArrangeOverride(arrangeSize); 
    }         
 }

我附上Event

 public static class CustomEventManager
{                        
    public static readonly RoutedEvent ArrangeEvent = EventManager.RegisterRoutedEvent("Arrange",
                                RoutingStrategy.Bubble,
                                typeof(RoutedEventHandler),
                                typeof(CustomEventManager));

    internal static void RaiseArrangeEvent(UIElement target)
    {
        var args = new RoutedEventArgs(ArrangeEvent);
        target.RaiseEvent(args);            
    }       
} 

此面板是项目控件的项目面板, 将 ItemsTemplate 作为 EventTrigger,在引发附加事件时我不想触发:

  <DataTemplate DataType="{x:Type local:Checker}" x:Key="CheckerTempalte">

    <Ellipse x:Name="ellipse" Style="{StaticResource checkerStyle}">
        <Ellipse.Triggers>
            <EventTrigger RoutedEvent="local:CustomEventManager.Arrange">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" 
                                    Storyboard.TargetName="ellipse"
                                >
                            <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
                            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="{Binding Val}" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>                    
        </Ellipse.Triggers>        
    </Ellipse>

事件触发没有触发,

也许我没有正确使用 AttachedEvents 或者它没有正确声明 我需要面板中的事件来传播和触发子元素中的 EventTriggers,

任何想法我做错了什么?

编辑:

在 dkozl 的洞察之后,我得出结论,我需要一个 AddXXXHandler 和 RemoveXXXHandler 以便 XAML 添加/删除 EventTrigger 的处理程序

    public static void AddArrangeHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie != null)
        {
            uie.AddHandler(CustomEventManager.ArrangeEvent, handler);
        }
    }

    public static void RemoveArrangeHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie != null)
        {
            uie.RemoveHandler(CustomEventManager.ArrangeEvent, handler);
        }
    } 

但仍然没有任何反应,而且我从未使用过这些方法。

编辑 2:

感谢下面dkozl的cmets,

为每个子元素引发事件,因为椭圆在 视觉树。

  protected override Size ArrangeOverride(Size arrangeSize)
  {                    
      foreach (UIElement child in children)
      {                        
           CustomEventManager.RaiseArrangeEvent(child);                                            
      } 
  }

但仍然没有任何反应,iv'e 还通过提供“EventTrigger”测试了“StoryBoard” 'MouseEnter' 事件并将我的鼠标移到元素上,它工作正常。

不过,即使在每个 Ellipse 上引发事件仍然不起作用...... 有任何想法吗 ?

另一个有趣的地方是子元素实际上是'Checker'类型 而不是 DataTemplate 代表的椭圆,我不明白“Checker”是如何被视为 UIElement 的。?

【问题讨论】:

    标签: wpf eventtrigger routed-events


    【解决方案1】:

    您创建的是标准RoutedEvent,而不是附加的。附加事件的添加/删除处理程序不同。您将需要两个单独的方法(AddArrangeChildrenHandler 和 RemoveArrangeChildrenHandler)。已经在MSDN网站上解释过了

    更新: 我已将更新的Ellipse 定义和CustomEventManager 类复制到我的应用程序中,添加了单击时调用CustomEventManager.RaiseArrangeEvent(ellipse); 的测试按钮,它适用于我。

    我还必须添加 TransformGroupEllipse.RenderTransorm,第四个转换是 TranslateTransform 以使其像示例中一样工作

    UPDATE2: 事件在Ellipse 所在的面板上引发,这意味着冒泡事件永远不会到达它,因为它将从面板开始并沿着可视化树向上到达@987654330 @永远不会接触到面板的孩子

    【讨论】:

    • 是的,我现在看到了,我会更新问题,因为即使使用附加事件创建它时,它仍然不会触发 EventTrigger,在这种情况下,EventTrigger 实际上是 Handler。
    • 我编辑了问题,因此正确声明了附加事件。
    • 我假设您的 CustomEventManager 实现了两个静态方法 public static void AddArrangeHandler(DependencyObject d, RoutedEventHandler handler) {...}public static void RemoveArrangeHandler(DependencyObject d, RoutedEventHandler handler) {...}
    • 我不明白为什么我需要这里的处理程序,我在堆栈面板中没有处理程序,我不想每个面板项中的 EventTrigger 来处理事件,我假设EventTrigger 在幕后被翻译成 RoutedEventHandlers。
    • 您的CustomEventManager 类未处理事件。它仅用于将处理程序附加和删除到 UIElements,在您的情况下为 Ellipse,通常不支持此类事件。基本上AddArrangeHandler(...)(UIElement)d.AddHandler(...)RemoveArrangeHandler() 做相反的事情。它仍然由这个 UIElement 对象处理。
    【解决方案2】:

    您或许应该考虑使用纯代码方法来解决此问题。如果您希望在 XAML 中定义动画,您可以将它们静态资源化到 CompressToFitStackPanel 上的属性中。但是,如果您的 DataTemplate 指的是按索引进行的特定转换,那么您肯定会失去 DataTemplate'ing 的功能和抽象。

    重新评估您的问题空间以及设计应该解决的问题。使用 ILSpy 或 Reflector 分析其他面板如何解决属性或附加依赖属性(Grid.Column、Grid.Row)的问题。

    把更多的负担放在新的布局面板上,而不是那些使用它的人身上。

    祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      相关资源
      最近更新 更多