2011-05-30 60 views
1

請考慮下面的代碼:WPF GoToStateAction不點火使用DataTrigger

<Window>  
    <Window.Tag> 
     <Button x:Name="myButton"/> 
    </Window.Tag> 

    <Grid> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup> 
       <VisualState x:Name="VisualState"> 
        <Storyboard> 
         <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas"> 
          <EasingColorKeyFrame KeyTime="0" Value="Red"/> 
         </ColorAnimationUsingKeyFrames> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 

     <Canvas x:Name="canvas" Background="White"> 
      <i:Interaction.Triggers> 
       <ei:DataTrigger Value="True"> 
        <ei:DataTrigger.Binding> 
         <Binding Path="Equals"> 
          <Binding.Source> 
           <local:DependencyObjectComparer X="{x:Reference myButton}" Y="{x:Reference myButton}"/> 
          </Binding.Source> 
         </Binding> 
        </ei:DataTrigger.Binding> 
        <ei:GoToStateAction StateName="VisualState"/> 
       </ei:DataTrigger> 
       <i:EventTrigger EventName="MouseLeftButtonDown"> 
        <ei:GoToStateAction StateName="VisualState"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers>   
     </Canvas> 
    </Grid> 
</Window> 

的DependencyObjectComparer那樣 - suprinsingly - 平等比較 「X」 和 「Y」:

public class EqualityComparer<T> : IEqualityComparer<T> 
{ 
    public EqualityComparer(Func<T, T, bool> comparer) 
    { 
     Contract.Requires(comparer != null); 
     this.m_comparer = comparer; 
    } 

    public bool Equals(T x, T y) 
    { 
     return this.m_comparer(x, y); 
    } 

    public int GetHashCode(T obj) 
    { 
     return obj.ToString().ToLower().GetHashCode(); 
    } 

    private readonly Func<T, T, bool> m_comparer; 
} 

public class LazyEqualityComparer<T> : DependencyObject 
{ 
    static LazyEqualityComparer() 
    { 
     EqualsProperty = DependencyProperty.Register 
     (
      "Equals", 
      typeof(bool), 
      typeof(LazyEqualityComparer<T>), 
      null 
     ); 
    } 

    public static readonly DependencyProperty EqualsProperty; 

    public Func<T, T, bool> Comparer { get; set; } 

    public T X 
    { 
     get { return this.m_x; } 
     set 
     { 
      if (!object.Equals(this.m_x, value)) 
      { 
       this.m_x = value; 
       this.OnComperandChanged(); 
      } 
     } 
    } 

    public T Y 
    { 
     get { return this.m_y; } 
     set 
     { 
      if (!object.Equals(this.m_y, value)) 
      { 
       this.m_y = value; 
       this.OnComperandChanged(); 
      } 
     } 
    } 

    [Bindable(true)] 
    new public bool Equals 
    { 
     get { return (bool)this.GetValue(EqualsProperty); } 
     private set { this.SetValue(EqualsProperty, value); } 
    } 

    private void OnComperandChanged() 
    { 
     this.Equals = new EqualityComparer<T>(
      this.Comparer != null ? this.Comparer : (x, y) => x.Equals(y) 
     ).Equals(this.X, this.Y); 
    } 

    private T m_x; 
    private T m_y; 
} 


public class DependencyObjectComparer : LazyEqualityComparer<DependencyObject> { } 

雖然EventTrigger在點擊畫布時觸發,但DataTrigger不是,而它確實返回期望值(true)。這種行爲和這種觸發器之間是否存在任何不兼容?

我不知道我在做什麼錯在這裏。謝謝你的幫助。

回答

1

最後發現自己的解決方案:

<Window>  
    <Window.Tag> 
     <Button x:Name="myButton"/> 
    </Window.Tag> 

    <Grid>    
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup> 
       <VisualState x:Name="Default"/> 
       <VisualState x:Name="VisualState"> 
        <Storyboard> 
         <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas"> 
          <EasingColorKeyFrame KeyTime="0" Value="Red"/> 
         </ColorAnimationUsingKeyFrames> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 

     <Canvas x:Name="canvas" Background="White">   
      <i:Interaction.Triggers>     
       <ei:PropertyChangedTrigger Binding="{Binding Tag, ElementName=window}">     
        <i:Interaction.Behaviors> 
         <ei:ConditionBehavior> 
          <ei:ConditionalExpression> 
           <ei:ComparisonCondition LeftOperand="{Binding Tag, ElementName=window}" RightOperand="{x:Reference myButton}"/> 
          </ei:ConditionalExpression> 
         </ei:ConditionBehavior> 
        </i:Interaction.Behaviors> 
        <ei:GoToStateAction StateName="VisualState"/>      
       </ei:PropertyChangedTrigger> 
       <ei:PropertyChangedTrigger Binding="{Binding Tag, ElementName=window}">     
        <i:Interaction.Behaviors> 
         <ei:ConditionBehavior> 
          <ei:ConditionalExpression> 
           <ei:ComparisonCondition LeftOperand="{Binding Tag, ElementName=window}" RightOperand="{x:Reference myButton}" Operator="NotEqual"/> 
          </ei:ConditionalExpression> 
         </ei:ConditionBehavior> 
        </i:Interaction.Behaviors> 
        <ei:GoToStateAction StateName="Default"/>      
       </ei:PropertyChangedTrigger> 
      </i:Interaction.Triggers> 
     </Canvas> 
    </Grid> 
</Window> 

有誰知道它是否可以設置一個假國家,而無需再次書寫與改變操作條件?就像那個DataStateBehavior有可能。