wpf 进度条在上次 ProgressChanged 时未更新

2023-12-09

我制作了一些 UI,其中有 ProgressBar。使用MVVM模式。

XAML:

<ProgressBar Grid.Row="2" Minimum="0" Maximum="100" Value="{Binding CurrentProgress, Mode=OneWay}"/>

视图模型(简化):

class MyClass : ViewModelBase
{
    /// <summary>
    /// Fields
    /// </summary>
    private int _currentProgress;
    private readonly BackgroundWorker _worker;
    private int _step; 

    /// <summary>
    /// Properties
    /// </summary>
    public int CurrentProgress
    {
        get
        {
            return _currentProgress;
        }
        set
        {
            if (_currentProgress != value)
            {
                _currentProgress = value;
                RaisePropertyChanged("CurrentProgress");
            }
        }
    }

    /// <summary>
    /// Constructor
    /// </summary>
    public MyClass()
    {
        _step = 10;
        _currentProgress = 0;
        _worker = new BackgroundWorker();
        _worker.DoWork += DoWork;
        _worker.WorkerReportsProgress = true;
        _worker.ProgressChanged += ProgressChanged;
        _worker.RunWorkerCompleted += RunWorkerCompleted;
    }

    /// <summary>
    /// Command 
    /// </summary>
    private RelayCommand _myCommand;
    public RelayCommand MyCommand
    {
        get
        {
            return _myCommand ?? (_myCommand =
                new RelayCommand(_worker.RunWorkerAsync, CanMyCommand));
        }
    }

    private bool CanMyCommand()
    {
        return true;
    }

    /// <summary>
    /// Handlers
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 10; i++)
            ConsumingMethod();
    }

    private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Thread.Sleep(5000);
        Messenger.Default.Send(new CloseAddDocumentWindow(String.Empty));
    }

    private void ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        CurrentProgress = e.ProgressPercentage;
    }

    /// <summary>
    /// Method
    /// </summary>
    private void ConsumingMethod()
    {
        CurrentProgress += _step;
    }
}

代码隐藏:

 Messenger.Default.Register<CloseAddDocumentWindow>(this, nm =>
 {
      if (nm.Sender == DataContext)
          Close();
 });

So, this

 Messenger.Default.Send(new CloseAddDocumentWindow(String.Empty));

是问题所在。如您所见,该行关闭窗口。如果我评论该行,进度条效果很好。 10、20、30……100% 我明白了。但除此之外,进度条看起来像 10、20、30……90%,一些等待和窗口关闭!我尝试使用 Thread.Sleep(5000) 来给进度条一些时间来绘制。但即便如此也无济于事。那么,如果窗口立即关闭,我怎样才能看到最后的百分比变化呢?


对于任何未来的读者:

后台工作者的 DoWork在新线程上执行,例如允许在不锁定 UI 的情况下进行工作。这RunWorkerCompleted功能将在调用线程上为您运行,这意味着它返回到 UI 线程,并且此处完成的任何工作都可以锁定 UI。

ProgressBar 正在通过不同的线程进行更新,从而允许其更新。但一旦该值从 90 变为 100,UI 就会执行此“关闭”操作。当OP添加Sleep(5000)时;它位于 UI 线程 Completed 中,因此阻止 ProgressBar 显示完整的 100%。

解决方案是将睡眠从 Completed 移至 DoWork 循环,或者至少在循环之后,在发送关闭之前查看 ProgressBar 达到 100%。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

wpf 进度条在上次 ProgressChanged 时未更新 的相关文章

  • StockTrader RI > 控制器、演示者,WTF?

    我目前正在学习如何通过 Prism 复合 WPF 项目高级使用 WPF 我观看了很多视频和示例 演示应用程序 StockTraderRI 让我提出了这个问题 以下各部分的具体作用是什么 SomethingService 好的 这是管理数据的
  • 如何将图像转换为字节数组[重复]

    这个问题在这里已经有答案了 有人能建议我如何将图像转换为字节数组 反之亦然吗 我正在开发 WPF 应用程序并使用流读取器 将图像更改为字节数组的示例代码 public byte ImageToByteArray System Drawing
  • DispatcherTimer Stop 不停止

    更新 我把完整的代码放出来供参考 我正在尝试使用 Dispatcher 方法而不是 Forms Timer 我在方法结束时停止了 但在停止之前它一直循环多次 什么地方出了错 顺便说一句 我必须提到我确实在计时器 if 语句中使用了 Mess
  • 如何动态更改 WPF 中 DataGridTextColumn 绑定上的转换器?

    我真的不明白 WPF 和 XAML 并且继承了一些写得很糟糕的代码 所以我可能会扼杀它 但这里是 我继承了一个绑定到 Person 对象列表 在代码后面 的 DataGrid 其中必要的 DataGridTextColumn 在 XAML
  • 在wpf中快速生成ViewModel属性?

    看完之后本文 http msdn microsoft com en us magazine dd419663 aspx a 在我的中有以下代码PersonViewModel class public Jurisdiction Country
  • 指定 Xaml 中开始标记和结束标记之间的属性

    考虑以下 Xaml
  • 将 RenderTargetBitmap 转换为 System.Drawing.Image

    我有 3D WPF 视觉对象 我想将其传递到 Excel 单元格 通过剪贴板缓冲区 对于 普通 BMP 图像 它可以工作 但我不知道如何转换RenderTargetBitmap 我的代码如下所示 System Windows Media I
  • 如何在fragment中使用ViewModel?

    我正在使用 MVVM 架构 我有一个活动和一些片段 我想在活动中的API中发出请求 然后使用ViewModel 感谢获得的数据 将它们显示在片段中 我该怎么做 我当前的解决方案不起作用 活动 viewModelRoutesFragment
  • 从 WPF 窗口中删除图标

    我可以使用 WinApi 从 WPF 窗口中删除窗口图标 但是当我仅运行 WPF 项目的可执行文件时 我会在应用程序窗口中再次获得该图标 如何删除该图标 From WPF教程 http www wpftutorial net RemoveI
  • 列表框未虚拟化

    我有一个未虚拟化的列表框 我显然错过了一些东西 但找不到它 它实际上是一个列表框内的一个列表框 外部列表框有一个 ItemTemplate 其中包含一个 Expander Expander 用于显示一组项目 Expander 的内容是显示项
  • 如何将启动时窗口的位置定位到用户屏幕的右侧?

    我目前正在用 C 创建一个类似侧边栏的 WPF 应用程序 当用户启动应用程序时 我希望窗口自动将其自身定位到用户屏幕的一侧 我尝试了一些方法和谷歌搜索 但没有找到任何帮助 这是我正在尝试做的事情的一个例子 http prntscr com
  • MVVM基础视图模型类

    我正在努力创建一个基本视图模型类 ViewModelBase 是一个抽象类 我想定义我希望所有其他派生视图模型实现的属性 其中一个属性是 ObservableCollection public abstract ObservableColl
  • 访问 ControlTemplate 内的控件

    这是 xaml
  • 给 MVVM 中的 View 一些命令

    假设我有一些用户控制权 用户控件有一些子窗口 用户控制用户想要关闭某种类型的子窗口 用户控制代码后面有一个方法 public void CloseChildWindows ChildWindowType type 但我无法调用此方法 因为我
  • CanExecute 何时被调用?

    在演示中 我有一个按钮可以切换布尔字段isAsking 我创建了一个命令 该命令仅在以下情况下执行isAsking true 一旦我按下切换按钮 okButton IsEnable立即更改 这表明该命令发现了更改isAsking 我感到很困
  • WPF 用户控件;触发器和更改其他控件

    我创建了一个 WPF UserControl 其中包含一个按钮和一个组合框 我想根据鼠标的位置更改两者的样式 因此鼠标悬停的 UIElement 的颜色为黑色 另一个的颜色为红色 如果两者均未设置样式 则将应用默认样式 别担心 这个噩梦般的
  • wpf自定义控件:另一个矩形内的可拖动/可调整大小的矩形

    我正在研究一个带有两个矩形的控件 一个在另一个矩形内 我希望用户能够拖动内部矩形 调整其大小 如果可能的话 也可以在外部矩形的边界内旋转它 这些值应该是可绑定的 以便我可以在更新时将这些值存储在我的数据源中 是否已经有这样的控件或者有人有任
  • 如何用ListBox制作自定义控件?

    我想用自定义的项目模板制作水平ListBox 所以我制作了它的基本模板 但是 我找不到将 事物 绑定到 WPF XAML 的示例 尤其是在 ListBox 填充了自定义项的情况下 我只是想动态添加 删除列表框中的项目 其中包含图像 标签 组
  • 获取上下文菜单的控制

    我有一个如下所示的上下文菜单 A 1 2 3 选择 1 2 或 3 后 我需要访问调用上下文菜单的对象 意思是如果这是 textbox1 的上下文菜单 那么我需要访问该对象 我该怎么做 忘了说了 这是一个WPF应用程序 所以我使用 Syst
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n

随机推荐