Yesterday I failed to get an answer, but perhaps I did not understa开发者_开发百科nd the problem deep enough to formulate correct question.
The story is about animating ListBox height. Here are subsequent screenshots:
a) "Medium" is a TextBlock
b) "Medium" TextBlock gets replaced by a ListBox. The user selects an item. That initiates animation of the ListBox.Height. After the animation completes, the ListBox is replaced by original TextBlock. (Disregard the differences in data. Collection of the images was a painfull process, when I had to work with rendered frames. One of the images was shot for different record.)
This sequence works with occasional flickering. I wanted to know what's going on and after a while I got this screenshot:
What you see is the first frame after Storyboard.Completed event was intercepted. As far I understand this is the final result from the Storyboard.
Notes:
I checked the visual tree at this instant and did not find anything suspiceous.
This is just one of the effects that happen. Another frequent case is a resized 1-line ListBox with blue hatching; in this case all elements above the listbox disappear. 3rd possibility is a diagonal red line over the whole screen.
Here is the code defining the Storyboard:
private Storyboard GetDropDownAnimation(double from, double to)
{
double secs = this.IsExpanded ? 0.2 : 0.4;
CubicEase ease = new CubicEase() { EasingMode = EasingMode.EaseInOut };
DoubleAnimation animation = new DoubleAnimation()
{
Duration = new Duration(TimeSpan.FromSeconds(secs)),
From = from,
To = to,
FillBehavior = FillBehavior.HoldEnd,
EasingFunction = ease
};
Debug.WriteLine("Animation Height {0} -> {1}", from, to);
Storyboard.SetTarget(animation, this);
Storyboard.SetTargetProperty(animation, new PropertyPath("Height"));
Storyboard sb = new Storyboard();
sb.Children.Add(animation);
return sb;
}
I could explain other tricks done (for a long time I was convinced that the problem is there), but it looks like the problem concerns only the animation itself.
Anybody able to explain what's going on?
Have a look at these before you continue this way it might make your life a bit easier :)
That said, have a look at the starting value of the animation (from) and see if it is correct.
If all else fails you could start with a fully transparent listbox.
I made some progress on the problem that may be worth of reporting.
At first I replaced Storyboard by own animations. I started by using CompositionTarget.Rendering callbacks. The code is fairly trivial: In the callback you need to update the ListBox height proportionally to the elapsed time. I double-checked that for each height change there is one LayoutUpdated event, in other words the screen is in sync all the time. (A pleasant surprise.)
The result: Flickering remained.
Conclusion: Storyboard is innocent.
Then I found something interesting: Because the height manipulation was in my hands I simply rounded the value to the whole multiple of the row height. And guess what - flickering disappeared!
Note the ListBox in question is set up using ItemsSource and DisplayMemberPath that refers to a string property. ItemTemplate is not set. In other words pretty standard ListBox use.
It is not an answer, I know, yet I find it interesting.
精彩评论