2012-12-12 51 views
1

我需要使用具有交互觸發器一些附加條件,e.g:交互觸發條件和其他適配器

在上一個事件的反應我想執行命令,但只有當一個狀態匹配。另外我希望命令會延遲執行。我可以用這個僞xaml來表達這個。

<ci:RoutedEventTrigger Event="{x:Static Selector.SelectionChangedEvent}"> 
    <li:TriggerCondition ActualValue="{Binding Value}" ExpectedValue="{StaticResource foo}"> 
    <li:DelayAction DelayTime="{StaticResource delayTime}"> 
     <InvokeCommandAction CommandName="{StaticResourc commandName}"/> 
    </li:DelayAction> 
    </li:TriggerCondition> 
</ci:RoutedEventTrigger> 

我試着編寫TriggerCondition和DelayAction類,但幾乎所有的交互性代碼都是內部的。

所以問題是我如何達到預期的行爲? 寫入RoutedEventTrigger條件和延遲看起來不那麼通用,而且我有InputBindingTrigger和更多。

在此先感謝

UPDATE: 我做了我想用反射什麼,但我仍然在尋找你的建議怎麼做,以正確的方式:)

[ContentProperty("Actions")] 
    public abstract class TriggerDecorator : TriggerAction<DependencyObject> 
    { 
    private static readonly DependencyPropertyKey ActionsPropertyKey = 
     DependencyProperty.RegisterReadOnly("Actions", typeof (TriggerActionCollection),typeof (TriggerDecorator), new FrameworkPropertyMetadata()); 
    public static readonly DependencyProperty ActionsProperty = ActionsPropertyKey.DependencyProperty; 
    public TriggerActionCollection Actions 
    { 
     get { return (TriggerActionCollection) GetValue(ActionsProperty); } 
    } 

    private readonly MethodInfo myTriggerAction_CallInvokeMethod; 

    public TriggerDecorator() 
    { 
     var triggerActionType = typeof (TriggerAction); 
     myTriggerAction_CallInvokeMethod = triggerActionType.GetMethod("CallInvoke", BindingFlags.Instance | BindingFlags.NonPublic); 
     if(myTriggerAction_CallInvokeMethod == null) 
     throw new InvalidOperationException(); 

     var actionCollection = (TriggerActionCollection)Activator.CreateInstance(typeof(TriggerActionCollection), true); 
     SetValue(ActionsPropertyKey, actionCollection); 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     if(AssociatedObject == null) 
     return; 
     Actions.Attach(AssociatedObject); 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     Actions.Detach(); 
    } 

    protected void ExecuteActions(object parameter) 
    { 
     var param = new[] {parameter}; 
     foreach (var triggerAction in Actions) 
     myTriggerAction_CallInvokeMethod.Invoke(triggerAction, param); 
    } 
    } 

回答

0

你可以定製EventTrigger

類似這樣的東西應該可以工作:

public sealed class DelayAction : System.Windows.Interactivity.EventTrigger 
    { 
     private EventArgs _eventArgs; 
     private DispatcherTimer _delayTimer; 

     public static readonly DependencyProperty DelayProperty = 
      DependencyProperty.Register("Delay", typeof(double) 
      , typeof(DelayAction), new PropertyMetadata(0.0)); 

     public double Delay 
     { 
      get { return (double)base.GetValue(DelayProperty); } 
      set { base.SetValue(DelayProperty, value); } 
     } 

     protected override void OnDetaching() 
     { 
      if (_delayTimer != null) 
      { 
       _delayTimer.Stop(); 
       _delayTimer = null; 
      } 
      base.OnDetaching(); 
     } 

     protected override void OnEvent(EventArgs eventArgs) 
     { 
      if (_delayTimer != null) 
      { 
       _delayTimer.Stop(); 
      } 
      _eventArgs = eventArgs; 
      _delayTimer = new DispatcherTimer(); 
      _delayTimer.Interval = TimeSpan.FromMilliseconds(this.Delay); 
      _delayTimer.Tick += new EventHandler(TimerTick); 
      _delayTimer.Start(); 
     } 

     private void TimerTick(object sender, EventArgs e) 
     { 
      this._delayTimer.Stop(); 
      base.InvokeActions(this._eventArgs); 
     } 
    } 

用法:

<Button Click="Button_Click"> 
    <i:Interaction.Triggers> 
     <myTriggers:DelayAction Delay="1000" EventName="Click"> 
     // do stuff 
     </myTriggers:DelayAction> 
    </i:Interaction.Triggers> 
</Button> 
+0

感謝。但「寫入RoutedEventTrigger的條件和延遲看起來不那麼通用,此外我有InputBindingTrigger和更多。」 –