C# Winforms - ProgressBar 无法正确显示和重置

标签 c# .net visual-studio winforms

我有一个 Windows 桌面应用程序,正在使用 Visual Basic 中的 Windows 窗体编写。在这个应用程序中,我想显示一个简单的进度条,但我遇到了一个奇怪的问题。下面是更新进度条的简单 for 循环示例:

pBar.Visible = true;
// pBar.Minimum and pBar.Step are both set to 1 using the properties pane in the design page
pBar.Maximum = 100;
for (int j = 0; j < 100; j++) {
    double pow = Math.Pow(j, j); //Calculation
    pBar.PerformStep();
}

上面的工作正常,但是,我希望能够重置进度条以便稍后再次使用它。我以为我可以在 for 循环之后简单地设置 pBar.Value = 1 ,但奇怪的是这会破坏进度条。条形图根本没有填满,而不是像以前那样稳步增加。如果我设置 pBar.Value = 50,则条形图从中间点开始并且不会移动。它的行为就像 pBar.Value 在 for 循环之前执行,或者 pBar.Value 在每次循环迭代期间设置(我已经确保我没有错误地将 pBar.Value 语句放入 for 循环中)。

我认为发生这种情况的唯一原因是 C# 正在异步运行我的 for 循环,并且该值立即被设置,然后由于某种原因它没有被更新。我尝试四处寻找这个问题的答案,但到目前为止,我发现的只是创建后台工作人员的方法(我对此不感兴趣),并且我重置进度条的方法应该正在工作...

为什么会发生这种情况?

最佳答案

好的,这是我尝试回答您的问题:

我认为当您在循环后将进度条的值重置为 1 时,进度条不会“更新”。我认为进度条的整个动画很假。

我查看了 ProgressBar 的源代码 here 。我们注意到 ProgressBar.ValueProgressBar.PerformStep 最终都会调用 UpdatePos依次发送 PBM_SETPOS发送给底层 native 控件的消息。然后 MSDN 告诉我们,每次收到此消息时,该栏都应该重新绘制。

但是,我怀疑该栏的“真实”动画在某种程度上被控件虚拟化了。我的猜测是,PBM_SETPOS 消息会立即考虑到位置值(我们不希望我们的柱形图每次都不知道它的值),但它们也必须发送到一些动画队列。

动画可能需要相当长的时间,如果发生需要动画停止或修改(例如向后播放)的情况,动画就会被取消...... 假设您交替使用值 1 和 51,而不是增加当前值,您期望什么样的动画?

我通过在代码中替换 pBar.PerformStep(); 来模拟这一点:

pBar.Value = j % 2 * 50 + 1;

当然,没有尾随的pBar.Value = 1;

生成的动画不是 1 到 51 之间令人作呕的往返,而是从 1 到 51 的干净平滑的过渡:)

我认为这证明了我的观点,即动画正在自行选择它想要的值,因此当快速在 100 之后设置 1 时,动画引擎决定不渲染任何内容。

因此,如果您想避免这种效果,最简单的方法是在使用进度条值之前将其重置为 1,而不是在使用之后(顺便说一句,不假设进度条值可能会被证明是更好的编程实践)使用时为1)。

<小时/>

PS:最后一点,同样的现象被用作一种技巧,在动画有时间完成之前强制进度条上的高值 here .

就您而言,您可以:

private void GoSlowlyTo100() => pBar.Value = 100;
private void GoQuicklyTo100()
{
    pBar.Maximum = 101;
    pBar.Value = 101;
    pBar.Maximum = 100;
    pBar.Value = 100;
}

希望这能回答您的问题!

关于C# Winforms - ProgressBar 无法正确显示和重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59539581/

相关文章:

c# - SQLite 异步连接缺少 WithChildren 方法

c++ - Visual C++ 如何为 Delphi 导出 x64 DLL 函数

c# - 无论如何在 C# 中缓存函数/方法

c# - 确定反射类型是否可以转换为另一个反射类型

.net - CreateRibbonExtensibilityObject 仅创建一个功能区对象 - Outlook 2010 Addin

C# : Characters do not display well when in Console, 为什么?

c - 在 Visual Studio 中设置 FILE_ATTRIBUTE_DEVICE

c# - Office 365/Sharepoint网站开发

c# - Ef Core 中的数学绝对值?

c# - 如何在 LINQ 中查询 ID-名称对中的重复名称?