ProgressBar在Windows窗体中很慢
我正在使用Windows Vista和Visual Studio 2010.创建.Net 4 Windows窗体应用程序。 删除默认表单上的进度条,添加代码以处理表单加载事件并执行progressBar1.Value = 100;
那里。
开始调试,你会看到动画在大约半秒内将进度条移动到100。
我的项目需要2个进度条。 一个用于“全局进展”,第二个用于“当前步进”,因此第二个从0到100,并且回到0以进行下一步。 问题是,由于某些快速步骤的进度条缓慢,它永远不会达到100并且看起来很奇怪。
有没有办法摆脱那个动画? 在WPF中没关系,但我宁愿继续使用Windows Forms。
这就是Vista / 7进度条的设计方式。 当您更改进度条的值时,该栏会逐渐动画到该值。
我知道避免这个问题的唯一方法是在更新进度条时倒退,如下所示:
progressBar1.Value = n; if (n>0) progressBar1.Value = n-1;
有关更完整的讨论,请参阅更改值时禁用.NET进度条动画?
借助进度条和Reinhart的扩展方法在相关问题中向后推进Heffernan的提示 ,我提出了自己的解决方案。
该解决方案非常无缝,并成功处理了值为Maximum
时将遇到的问题。 ProgressBar
这种扩展方法减轻了在Windows Vista和7上运行时WinForms ProgressBar
控件中存在的渐进式动画样式导致的滞后 (我还没有在Windows 8上测试过)。
public static class ExtensionMethods { /// /// Sets the progress bar value, without using 'Windows Aero' animation. /// This is to work around a known WinForms issue where the progress bar /// is slow to update. /// public static void SetProgressNoAnimation(this ProgressBar pb, int value) { // To get around the progressive animation, we need to move the // progress bar backwards. if (value == pb.Maximum) { // Special case as value can't be set greater than Maximum. pb.Maximum = value + 1; // Temporarily Increase Maximum pb.Value = value + 1; // Move past pb.Maximum = value; // Reset maximum } else { pb.Value = value + 1; // Move past } pb.Value = value; // Move to correct value } }
样品用法:
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.SetProgressNoAnimation(e.ProgressPercentage); }
您可以轻松编写自定义进度条以显示其值而无需动画。 以下是一个简单的实现,用于显示从0到100的进度并恢复为0。
public class ProgressBarDirectRender : UserControl { private int _value; public int Value { get { return _value; } set { if (value < 0 || value > 100) throw new ArgumentOutOfRangeException("value"); _value = value; const int margin = 1; using (var g = CreateGraphics()) { if (_value == 0) ProgressBarRenderer.DrawHorizontalBar(g, ClientRectangle); else { var rectangle = new Rectangle(ClientRectangle.X + margin, ClientRectangle.Y + margin, ClientRectangle.Width * _value / 100 - margin * 2, ClientRectangle.Height - margin * 2); ProgressBarRenderer.DrawHorizontalChunks(g, rectangle); } } } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); ProgressBarRenderer.DrawHorizontalBar(e.Graphics, ClientRectangle); } }
我喜欢Derek W的答案 ,我设法找到了一个支持数据绑定的解决方案。 我从System.Windows.Forms.ProgressBar
inheritance并创建了新的可绑定属性。 否则它是一样的:
[DefaultBindingProperty("ValueNoAnimation")] public class NoAnimationProgressBar : ProgressBar { /// /// Sets the progress bar value, without using 'Windows Aero' animation. /// This is to work around (hack) for a known WinForms issue where the progress bar /// is slow to update. /// public int ValueNoAnimation { get => Value; set { // To get around the progressive animation, we need to move the // progress bar backwards. if (value != Maximum) Value = value + 1; // Move past else { // Special case as value can't be set greater than Maximum. Maximum = value + 1; Value = value + 1; Maximum = value; } Value = value; // Move to correct value } } }
您可以像这样绑定到属性(viewModel有一个名为Value
的int属性):
上述就是C#学习教程:ProgressBar在Windows窗体中很慢分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
var dataSource = new BindingSource { DataSource = _viewModel }; progressBarBindingHack.DataBindings.Add("ValueNoAnimation", dataSource, "Value");
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1011133.html