Is it possible to give the condition within the EventTrigger?? I have written a following EventTrigger (Mouse.MouseLeave) for Radio button. I want this should not be trigged for an item which is in Checked condition (IsChecked=True).
<EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="border"> <BeginStoryboard Name="out_BeginStoryboard" Storyboard="{StaticResource out}" /> <RemoveStoryboard BeginStoryboardName="over_BeginStoryboard" /> </EventTrigger>
Please let me know how can I achieve this?
Thanks in advance.
You can't use EventTrigger in this way. WPF's RoutedEventHandler that invokes EventTriggers doesn't provide any mechanism for making the trigger conditional, and you can't fix this by subclassing TriggerAction because there is no protected Invoke() or Execute() action to override.
However this can be done quite easily using a custom class. Here's how it would be used:
<Border> <my:ConditionalEventTrigger.Triggers> <my:ConditionalEventTriggerCollection> <my:ConditionalEventTrigger RoutedEvent="Mouse.MouseLeave" Condition="{Binding IsChecked, ElementName=checkbox}"> <BeginStoryboard Name="out_BeginStoryboard" Storyboard="{StaticResource out}" /> <RemoveStoryboard BeginStoryboardName="over_BeginStoryboard" /> </my:ConditionalEventTrigger> </my:ConditionalEventTriggerCollection> </my:ConditionalEventTrigger.Triggers> ...
And here's how it would be implemented:
[ContentProperty("Actions")] public class ConditionalEventTrigger : FrameworkContentElement { public RoutedEvent RoutedEvent { get; set; } public List<TriggerAction> Actions { get; set; } // Condition public bool Condition { get { return (bool)GetValue(ConditionProperty); } set { SetValue(ConditionProperty, value); } } public static readonly DependencyProperty ConditionProperty = DependencyProperty.Register("Condition", typeof(bool), typeof(ConditionalEventTrigger)); // "Triggers" attached property public static ConditionalEventTriggerCollection GetTriggers(DependencyObject obj) { return (ConditionalEventTriggerCollection)obj.GetValue(TriggersProperty); } public static void SetTriggers(DependencyObject obj, ConditionalEventTriggerCollection value) { obj.SetValue(TriggersProperty, value); } public static readonly DependencyProperty TriggersProperty = DependencyProperty.RegisterAttached("Triggers", typeof(ConditionalEventTriggerCollection), typeof(ConditionalEventTrigger), new PropertyMetadata { PropertyChangedCallback = (obj, e) => { // When "Triggers" is set, register handlers for each trigger in the list var element = (FrameworkElement)obj; var triggers = (List<ConditionalEventTrigger>)e.NewValue; foreach(var trigger in triggers) element.AddHandler(trigger.RoutedEvent, new RoutedEventHandler((obj2, e2) => trigger.OnRoutedEvent(element))); } }); public ConditionalEventTrigger() { Actions = new List<TriggerAction>(); } // When an event fires, check the condition and if it is true fire the actions void OnRoutedEvent(FrameworkElement element) { DataContext = element.DataContext; // Allow data binding to access element properties if(Condition) { // Construct an EventTrigger containing the actions, then trigger it var dummyTrigger = new EventTrigger { RoutedEvent = _triggerActionsEvent }; foreach(var action in Actions) dummyTrigger.Actions.Add(action); element.Triggers.Add(dummyTrigger); try { element.RaiseEvent(new RoutedEventArgs(_triggerActionsEvent)); } finally { element.Triggers.Remove(dummyTrigger); } } } static RoutedEvent _triggerActionsEvent = EventManager.RegisterRoutedEvent("", RoutingStrategy.Direct, typeof(EventHandler), typeof(ConditionalEventTrigger)); } // Create collection type visible to XAML - since it is attached we cannot construct it in code public class ConditionalEventTriggerCollection : List<ConditionalEventTrigger> {}
Enjoy!
This is what worked for me...
I wanted to execute an animation based on the mouse hovering over a UI element and the UI element's associated owner being active (i.e. enabled to make a player move).
To support these requirements, I used relative source binding to overcome the lack of support for event trigger conditions.
Example:
<MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding RelativeSource={RelativeSource self}, Path=IsMouseOver}" Value="True" /> <Condition Binding="{Binding Path=IsPlayer1Active}" Value="True" /> </MultiDataTrigger.Conditions> <MultiDataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="#FF585454" Duration="0:0:.25"/> <ColorAnimation Storyboard.TargetProperty="Background.GradientStops[1].Color" To="Black" Duration="0:0:2"/> </Storyboard> </BeginStoryboard> </MultiDataTrigger.EnterActions> </MultiDataTrigger>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With