2

好的,所以我正在学习 C#/.NET 并且到目前为止一直坚持使用 winforms,但 WPF 似乎适合这个项目。

我有一个显示图像数组的 WrapPanel。有时这个数组会溢出窗口的范围。我正在尝试循环浏览“页面”,直到使用计时器显示所有图像。

我将在计时器经过事件处开始我的代码示例,此时我的 WrapPanel (wrapPanel1) 已经被填充并检查是否存在溢出:

public void t2_Elapsed(object source, ElapsedEventArgs e)
    {

        wrapPanel1.Dispatcher.BeginInvoke((ThreadStart)delegate 
        {
            remaining = Convert.ToInt32(imgCount) - (iteration*xDensity);

            label1.Content = iteration;
            label2.Content = remaining;
            label3.Content = imgCount;

            if (remaining <= 1)
            {
                Thickness marginTop = wrapPanel1.Margin;
                marginTop.Top = 0;
                wrapPanel1.Margin = marginTop;
                wrapPanel1.Children.Clear();
                t2.Stop();
                imgLayout();
            }

            else
            {
                Thickness marginTop = wrapPanel1.Margin;
                marginTop.Top = -((prevResY+10) * iteration);
                wrapPanel1.Margin = marginTop;
                iteration++;
            }
        });
    }

imgCount 是一个双精度数,表示 WrapPanel 中的图像总数(由于与代码中其他地方的另一个双精度交互,因此需要双精度)

xDensity 是用户定义的 int,用于设置水平显示的图像数量。

prevResY 是每张照片的高度(所有相同的分辨率),我添加 10 以占填充 WrapPanel 时设置的 5px 边距。通过乘以迭代,我总是将 wrapPanel1 向上移动 1 行。

imgLayout(); 重新开始这个过程,因为每次我浏览所有页面时,我都需要检查是否有任何新图像,并在最后敲掉任何旧图像。这一切都在 imgLayout() 中处理。

我更新标签只是为了在调试时可以密切关注它,它们返回的正是我期望的值。

正如您可能从问题标题中收集到的那样,我的问题是,随着 t2_elapsed 的每次迭代,间隔似乎会增加。如果我将间隔设置为 10 毫秒只是为了观察它的行为,那么延迟会呈指数增长。30 秒后延迟约为 25 秒,高于最初观察到的 0.1。RAM 使用率也在缓慢攀升,这向我表明循环重新启动时某些资源没有被处理,不确定这是原因还是单独的问题。

希望有人能帮忙!如果我做了一些愚蠢的事情,请告诉我,我还在学习!

非常感谢

- - 更新 - -

好的,所以我认为这与

wrapPanel1.Children.Clear(); 

线。我删除了它,让它填满,我没有延迟,但这显然不是最终的解决方案。无论我把那条线放在哪里,它都会重现问题。

----更新2 ----

好吧,我现在感觉很愚蠢。在启动计时器的 imgLayout() 方法的早些​​时候,我正在使用:

t2.Interval = new TimeSpan(0, 0, 0, 0, 5000);
t2.Tick += new EventHandler(t2_Tick);
t2.Start();

每次循环重新启动时,我都在愚蠢地声明事件处理程序。我将它设置在 Window_Loaded 方法中,它的工作方式与现在预期的完全一样,只是稍微整理了一下,并实现了一种一次滚动一整页而不是一行的方法。

4

1 回答 1

4

在处理 WPF 中的重复操作时,建议使用System.Windows.Threading.DispatcherTimer 。它将自动在 dispather 线程上执行其代码,而无需BeginInvoke.

于 2012-06-15T11:38:07.770 回答