我创建了一个特殊控件,它继承自FrameWork
元素。
有时会在控制代码中启动动画。
现在控件是在两个容器中创建的:
<UserControls:UniformOddButtonLine
Results="{Binding Results}"
ButtonStyle="{StaticResource OddButtonBaseStyle}"
Name="blubgrid1"
Grid.Column="0" />
<UniformGrid Rows="1" Grid.Column="1" Name="blubgrid2">
<UserControls:OddButton Result="{Binding Results[0]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[1]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[2]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[3]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[4]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[5]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[6]}" Style="{StaticResource OddButtonBaseStyle}" />
<UserControls:OddButton Result="{Binding Results[7]}" Style="{StaticResource OddButtonBaseStyle}" />
</UniformGrid>
UniformOddButtonLine
继承自UniformGrid
:
public sealed class UniformOddButtonLine : UniformGrid
{
public static readonly DependencyProperty ButtonStyleProperty =
DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(UniformOddButtonLine),
new PropertyMetadata(null, OnPropertyChanged));
public static readonly DependencyProperty ResultsProperty =
DependencyProperty.Register("Results", typeof(IEnumerable<IGameResultPresentationObject>), typeof(UniformOddButtonLine),
new PropertyMetadata(null, OnPropertyChanged));
public Style ButtonStyle
{
get
{
return (Style)GetValue(ButtonStyleProperty);
}
set
{
SetValue(ButtonStyleProperty, value);
}
}
public IEnumerable<IGameResultPresentationObject> Results
{
get
{
return (IEnumerable<IGameResultPresentationObject>)GetValue(ResultsProperty);
}
set
{
SetValue(ResultsProperty, value);
}
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as UniformOddButtonLine;
if (control == null)
{
return;
}
control.RecreateButtons();
}
private void RecreateButtons()
{
this.Children.Clear();
var style = this.ButtonStyle ?? (Style)this.FindResource("OddButtonBaseStyle");
var i = 0;
if (Results != null && Results.Any())
{
foreach (var button in this.Results.Select(result => new OddButton
{
Result = result,
Style = style
}))
{
var binding = new Binding("Results[" + (i++) + "]");
button.SetBinding(OddButton.ResultProperty, binding);
this.Children.Add(button);
}
}
}
}
我甚至用WPF Inspector验证了视觉和视频。逻辑树在两种情况下都是100%相同。
但动画仅适用于“blubgrid2”中的按钮
但必定存在一些差异,导致动画无法在“blubgrid1”中运行
编辑:
以下是启动动画的代码:
private bool m_AnimationRunning;
private void StartOddChangeAnimation()
{
if (m_AnimationRunning)
{
return;
}
m_AnimationRunning = true;
var totalDuration = OddChangedFadeInDuration + OddChangedHoldDuration + OddChangedFadeOutDuration;
var changeAnimation = new DoubleAnimationUsingKeyFrames
{
Duration = totalDuration
};
changeAnimation.KeyFrames.Add(new LinearDoubleKeyFrame(1.0, OddChangedFadeInDuration));
changeAnimation.KeyFrames.Add(new LinearDoubleKeyFrame(1.0,
OddChangedFadeInDuration + OddChangedHoldDuration));
changeAnimation.KeyFrames.Add(new LinearDoubleKeyFrame(0.0, totalDuration));
changeAnimation.Completed += (sender, args) =>
{
m_AnimationRunning = false;
};
this.BeginAnimation(OddChangeImageOpacityProperty, changeAnimation);
}
更奇怪的是,当我在一些只包含上述XAML的演示项目中使用OddButton
类时,它在两种情况下都能正常工作。
只有在我们的业务应用中,XAML要复杂得多,我们才会遇到这个问题。
问题是OnRender
没有被调用:
protected override void OnRender(DrawingContext drawingContext)
{
if (this.OddChangeImageOpacity > 0.0 && this.OddChangeImageOpacity < 1.0)
{
Trace.WriteLine(this.Result.Id + " " + this.OddChangeImageOpacity);
}
// read into local variables to only execute the getter one time
var leftImage = GetImage(ImagePosition.Left);
var middleImage = GetImage(ImagePosition.Middle);
var rightImage = GetImage(ImagePosition.Right);
DrawImages(drawingContext, leftImage, middleImage, rightImage);
DrawOddChangeAnimationImages(drawingContext);
DrawOdd(drawingContext);
}
我跟踪了animated
属性,它在“blubgrid2”中工作正常,但在“blubgrid1”中它没有被调用,甚至认为视觉树是100%相同。
编辑:
更多信息......整个XAML都在resourcedictionary
中,我们在运行时解析它。
所以我真正看到的唯一区别是,在一种情况下,按钮是在解析文件时创建的,而在另一种情况下,它们是在加载主机控件时创建的。
EIDT:
发现了一些非常奇怪的东西,我添加了另一条痕迹:
private static void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as OddButton;
if (control == null)
{
return;
}
control.InvalidateVisual();
if (control.OddChangeImageOpacity > 0.0 && control.OddChangeImageOpacity < 1.0)
{
Trace.WriteLine("onvisualpropchanged: " + (control.Result == null ? "null" : control.Result.Id) + " " + control.OddChangeImageOpacity);
}
}
触发动画时的结果输出是:
onvisualpropchanged:60804205 0,444444666666667 onvisualpropchanged:null 0,444444666666667 onrender:60804205 0,444444666666667 onvisualpropchanged:60804205 0,666666666666667 onvisualpropchanged:null 0,666666666666667 onrender:60804205 0,666666666666667 onvisualpropchanged:60804205 0,888889333333333 onvisualpropchanged:null 0,888889333333333 onrender:60804205 0,888889333333333 onvisualpropchanged:60804205 0,888888666666667 onvisualpropchanged:null 08888866666666667 onrender:60804205 0,888888666666667 onvisualpropchanged:60804205 0,666666666666667 onvisualpropchanged:null 0,666666666666667 onrender:60804205 0,666666666666667 onvisualpropchanged:60804205 0,444444 onvisualpropchanged:null 0,444444 onrender:60804205 0,444444 onvisualpropchanged:60804205 0,222222 onvisualpropchanged:null 0,222222 onrender:60804205 0,222222
由于某种原因,Result属性设置为null