Reputation: 12533
I have a a custom Panel
that raises a RoutedEvent
which is defined globally in a static class :
public class CompressItemsToFitStackPanel : StackPanel
{
protected override Size ArrangeOverride(Size arrangeSize)
{
// some logic
// Raise Attached Event
CustomEventManager.RaiseArrangeEvent(this);
return base.ArrangeOverride(arrangeSize);
}
}
My attached 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);
}
}
this Panel is the items panel for an Items control , the ItemsTemplate as an EventTrigger which i wan't to fire when the attached event is raised:
<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>
The Event trigger is not triggered ,
Maybe i'm not using AttachedEvents correctly or it is not Declared correctly i need the event from the panel to propagate and trigger the EventTriggers in the Child elements ,
any ideas what i'm doing wrong ?
EDIT :
After dkozl's insight i came to the conclusion that i need an AddXXXHandler and RemoveXXXHandler in order for the XAML to add/ remove the handler for the 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);
}
}
but still nothing happens , and i never reach these methods .
EDIT 2 :
thanks to dkozl's comments below ,
the Event is raised for each child element , since he the ellipses are down the Visual Tree .
protected override Size ArrangeOverride(Size arrangeSize)
{
foreach (UIElement child in children)
{
CustomEventManager.RaiseArrangeEvent(child);
}
}
but still nothing happens , iv'e also tested the 'StoryBoard' by giving the 'EventTrigger' the 'MouseEnter' event and moving my mouse over the element , it works fine.
still , even raising the event on each Ellipse still does not work ... any ideas ?
Another point of interest is that the child elements are actually the 'Checker' type and not the Ellipse which the DataTemplate represents , i don't get how 'Checker' is considered a UIElement .?
Upvotes: 0
Views: 1021
Reputation: 752
You should maybe consider a code only approach to this problem. If you wish to define the animations in XAML you can possibly StaticResource them into properties on the CompressToFitStackPanel. But if your DataTemplate is referring to a specific transform by index you are definitely losing the power and abstraction of DataTemplate'ing.
Reevaluate your problem space and what the design is supposed to solve. Use ILSpy or Reflector to analyze how other Panels solved problems with properties or Attached Dependency Properties (Grid.Column, Grid.Row).
Place more of the burden on the new layout panel and less on those who use it.
Good luck.
Upvotes: 0
Reputation: 33364
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
Upvotes: 1