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!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…