Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 141是可以同时设置动画的WPF面板项目的最大数量吗?_C#_Wpf_Animation_Panel - Fatal编程技术网

C# 141是可以同时设置动画的WPF面板项目的最大数量吗?

C# 141是可以同时设置动画的WPF面板项目的最大数量吗?,c#,wpf,animation,panel,C#,Wpf,Animation,Panel,我用C语言设计了几个动画的面板s,它们都继承自一个基类,该基类在面板上执行实际动画。子类。直到最近,他们都工作得很好。。。但最近,我在一个集合中使用了一个包含大量项目的集合,我开始出现一些奇怪的视觉错误 当应用程序第一次加载项目时,第一个x数量的项目将正确显示,然后剩余的项目将全部显示在第一个位置(相互重叠)。如果我调整窗口大小或选择一个项目,它们都会重新排列以正确显示。(使用下面的示例代码,您必须调整窗口的大小,以查看它们是否正确。) 经过大量的抓头和调试后,我发现每个项目的动画代码中仍然有正

我用C语言设计了几个动画的
面板
s,它们都继承自一个基类,该基类在
面板上执行实际动画。子类
。直到最近,他们都工作得很好。。。但最近,我在一个集合中使用了一个包含大量项目的集合,我开始出现一些奇怪的视觉错误

当应用程序第一次加载项目时,第一个x数量的项目将正确显示,然后剩余的项目将全部显示在第一个位置(相互重叠)。如果我调整窗口大小或选择一个项目,它们都会重新排列以正确显示。(使用下面的示例代码,您必须调整窗口的大小,以查看它们是否正确。)

经过大量的抓头和调试后,我发现每个项目的动画代码中仍然有正确的值,但最后的x个项目根本没有动画。每个项目都肯定会通过动画代码,但最后的x个项目保留在动画
面板中设置的位置。ArrangeOverride
方法

为了在我的代码中找到问题,我创建了一个新的
UserControl
和动画
Panel
类,用最少的代码重新创建问题。这样做之后,我很惊讶这个问题仍然可以重现。对于我的示例代码中的141项,没有显示问题,但是对于更多项,问题就出现了

请原谅代码排得太长,但是有太多的东西要显示

动画StackPanel.cs类

public class AnimatedStackPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        double x = 0, y = 0;
        foreach (UIElement child in Children)
        {
            child.Measure(availableSize);
            x = Math.Max(x, availableSize.Width == double.PositiveInfinity ? child.DesiredSize.Width : availableSize.Width);
            y += child.DesiredSize.Height;
        }
        return new Size(availableSize.Width == double.PositiveInfinity ? x : availableSize.Width, availableSize.Height == double.PositiveInfinity ? y : availableSize.Height);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        if (this.Children == null || this.Children.Count == 0) return finalSize;
        Size previousChildSize = new Size();
        Point endPosition = new Point(0, 0);
        foreach (UIElement child in Children)
        {
            endPosition.Y += previousChildSize.Height;
            double childWidth = finalSize.Width;
            child.Arrange(new Rect(0, 0, childWidth, child.DesiredSize.Height));
            Point startPosition = new Point(endPosition.X, endPosition.Y + finalSize.Height);
            AnimatePosition(child, startPosition, endPosition, new TimeSpan(0, 0, 1));
            previousChildSize = child.DesiredSize;
        }
        return finalSize;
    }

    private void AnimatePosition(UIElement child, Point startPosition, Point endPosition, TimeSpan animationDuration)
    {
        DoubleAnimation xAnimation = new DoubleAnimation(startPosition.X, endPosition.X, animationDuration);
        DoubleAnimation yAnimation = new DoubleAnimation(startPosition.Y, endPosition.Y, animationDuration);
        TransformGroup transformGroup = child.RenderTransform as TransformGroup;
        if (transformGroup == null)
        {
            TranslateTransform translatationTransform = new TranslateTransform();
            transformGroup = new TransformGroup();
            transformGroup.Children.Add(translatationTransform);
            child.RenderTransform = transformGroup;
            child.RenderTransformOrigin = new Point(0, 0);
        }
        TranslateTransform translateTransform = (TranslateTransform)transformGroup.Children[0];
        translateTransform.BeginAnimation(TranslateTransform.XProperty, xAnimation, HandoffBehavior.Compose);
        translateTransform.BeginAnimation(TranslateTransform.YProperty, yAnimation, HandoffBehavior.Compose);
        //child.Arrange(new Rect(endPosition.X, endPosition.Y, child.DesiredSize.Width, child.DesiredSize.Height));
    }
}
AnimatedListBox.xaml
UserControl

<UserControl x:Class="WpfTest.Views.AnimatedListBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:WpfTest.Views.Controls">
    <UserControl.Resources>
        <ItemsPanelTemplate x:Key="AnimatedStackPanel">
            <Controls:AnimatedStackPanel />
        </ItemsPanelTemplate>
    </UserControl.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Data}" ItemsPanel="{StaticResource AnimatedStackPanel}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
    </Grid>
</UserControl>
在实验中,我发现了一些奇怪的东西。如果我将
面板.ArrangeOverride
方法中项目的位置更改为以下值,则会出现更多意外结果

child.Arrange(new Rect(endPosition.X, endPosition.Y, childWidth, child.DesiredSize.Height));
不知何故,这会更改实际(动画)结束位置,即项目结束时的位置。它引入了一些项目的双重间距。在项目开始其动画之前,将项目安排在其结束位置如何更改其最终结束位置?我错过了什么明显的东西吗

此外,如果在
AnimatedStackPanel.AnimatePosition
方法中取消注释注释注释行,并注释掉上面的两行(即,剪切动画并将项目直接移动到动画将移动到的相同末端位置),则您将看到问题再次消失。。。无论集合中有多少项,这都适用。这就是为什么我认为这个问题与动画有关


我发现的最后一件事是,对于项数据类型使用或不使用
DataTemplate
s都存在问题。。。我很确定这与动画有关。如果有人能看到我做错了什么,或者找到解决办法,我会非常感激,因为这件事让我感到困惑。有人能用示例代码重现这个问题吗?非常感谢。

Sheridan,我对您的代码示例进行了一些研究,我发现当您应用RenderTransform时,显然很重要。我没有在
AnimatePosition
中分配它,即在第一次运行ArrangeOverride时,我将代码移动到
MeasureOverride

protected override Size MeasureOverride(Size availableSize)
{
    double x = 0, y = 0;
    foreach (UIElement child in Children)
    {
        TransformGroup transformGroup = child.RenderTransform as TransformGroup;
        if (transformGroup == null)
        {
            TranslateTransform translatationTransform = new TranslateTransform();
            transformGroup = new TransformGroup();
            transformGroup.Children.Add(translatationTransform);
            child.RenderTransform = transformGroup;
            child.RenderTransformOrigin = new Point(0, 0);
        }

        child.Measure(availableSize);
        x = Math.Max(x, availableSize.Width == double.PositiveInfinity ? child.DesiredSize.Width : availableSize.Width);
        y += child.DesiredSize.Height;
    }
    return new Size(
        availableSize.Width == double.PositiveInfinity ? x : availableSize.Width,
        availableSize.Height == double.PositiveInfinity ? y : availableSize.Height);
}
现在,即使在第一次调用ArrangeOverride时,动画的行为也与预期一样。看起来最近的几个RenderTransforms在设置动画时还没有连接到控件


顺便说一下,在运行32位Windows 7的两个不同系统(双核和四核)上,我的最大数量是144个。

就我而言,额外+1也是如此!做得好!你到底是怎么计算出来的?另外,我想知道项目的最大数量,因为以前,我的项目数量大约是110个。报告:在64位Windows 8.1双核上,最大数量是144个
protected override Size MeasureOverride(Size availableSize)
{
    double x = 0, y = 0;
    foreach (UIElement child in Children)
    {
        TransformGroup transformGroup = child.RenderTransform as TransformGroup;
        if (transformGroup == null)
        {
            TranslateTransform translatationTransform = new TranslateTransform();
            transformGroup = new TransformGroup();
            transformGroup.Children.Add(translatationTransform);
            child.RenderTransform = transformGroup;
            child.RenderTransformOrigin = new Point(0, 0);
        }

        child.Measure(availableSize);
        x = Math.Max(x, availableSize.Width == double.PositiveInfinity ? child.DesiredSize.Width : availableSize.Width);
        y += child.DesiredSize.Height;
    }
    return new Size(
        availableSize.Width == double.PositiveInfinity ? x : availableSize.Width,
        availableSize.Height == double.PositiveInfinity ? y : availableSize.Height);
}