使用 DataTrigger 时 WPF GoToStateAction 不会触发
请考虑以下代码:
<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 确实会比较“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 不会,但它确实会返回预期的结果值(真)。这种Action和这种Trigger有什么不兼容的地方吗?
我不知道我在这里做错了什么。感谢您的帮助。
Please consider the following piece of code:
<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>
The DependencyObjectComparer does - suprinsingly - compare "X" and "Y" for equality:
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> { }
While the EventTrigger is firing when I'm clicking on the Canvas, the DataTrigger is not, while it does return the expected value (true). Is there any incompatibility between this kind of Action and this kind of Trigger?
I've no idea what I'm doing wrong here. Thank's for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最后自己找到了一个解决方案:
有谁知道是否可以设置 False-State 而无需再次使用更改的运算符编写条件?就像 DataStateBehavior 可以实现的那样。
Finally found a solution by myself:
Does anybody know if it's possible to set a False-State without writing the conditions with changed Operator again? Just like that what's possible with the DataStateBehavior.