0

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

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

  <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 在下面的评论,

为每个子元素引发事件,因为省略号位于 Visual Tree 的下方。

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

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

尽管如此,即使在每个 Ellipse 上引发事件仍然不起作用......有什么想法吗?

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

4

2 回答 2

1

What you've created is standard RoutedEvent, not an attached one. Add/Remove handler is different for attached events. You'll need two separate methods (AddArrangeChildrenHandler and RemoveArrangeChildrenHandler). It has been explained on MSDN site

UPDATE: I've copied updated Ellipse definition and CustomEventManager class into my application, added test button which calls CustomEventManager.RaiseArrangeEvent(ellipse); when clicked and it works for me.

I also had to add Ellipse.RenderTransorm of TransformGroup, fourth transformation being TranslateTransform to make it work like in the example

UPDATE2: Event is raised on the panel where the Ellipse is placed which means that bubbling event would never reach it as it will start from the panel and go up the visual tree to Window never reaching children of the panel

于 2013-05-18T15:12:56.893 回答
0

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

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

将更多的负担放在新的布局面板上,而减轻使用它的人的负担。

祝你好运。

于 2013-05-20T01:12:47.547 回答