由AttachedEvent触发EventTrigger

时间:2013-05-18 14:42:42

标签: wpf eventtrigger routed-events

我有一个自定义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);            
    }       
} 

此面板是Items控件的items面板, 将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的评论,

为每个子元素引发事件,因为他的省略号是向下的 视觉树。

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

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

然而,即使在每个Ellipse上引发事件仍然无效...... 有任何想法吗 ?

另一个兴趣点是子元素实际上是'Checker'类型 而不是DataTemplate所代表的Ellipse,我不知道'Checker'是如何被视为UIElement的。

2 个答案:

答案 0 :(得分:1)

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

上对其进行了解释

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

我还必须添加TransformGroup TranslateTransform,第四个转换为Ellipse,以使其像示例一样工作

UPDATE2:在放置Window的面板上引发事件,这意味着冒泡事件永远不会到达,因为它将从面板开始并向上移动可视树{{1}}永远不会接触小组的儿童

答案 1 :(得分:0)

您应该考虑仅针对此问题的代码方法。如果您希望在XAML中定义动画,可以将它们静态地转换为CompressToFitStackPanel上的属性。但是如果你的DataTemplate指的是索引的特定转换,你肯定会失去DataTemplate的功能和抽象。

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

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

祝你好运。