【问题标题】:WPF ProgressBar not updating its progress statusWPF ProgressBar 未更新其进度状态
【发布时间】:2012-06-21 13:31:15
【问题描述】:

我正在使用 wpf UserControl 替换 AutoCAD 选定图形文件中的文件中的文本。 wpf 控件将显示一个状态(ProgressBar),指示在任何给定时间处理的文件数。所以我提出了以下代码,但 ProgressBar 根本没有显示任何进度。这是相关代码的一部分。

XAML:

<ProgressBar HorizontalAlignment="Stretch" Name="pgrSearch" Minimum="0" Maximum="{Binding Path=ProgressBarMaximum}"
                 Value="{Binding Path=ProgressBarCurrent}" Height="20" Margin="10"  />

代码隐藏:

public partial class ReplaceUserControl : UserControl, INotifyPropertyChanged {
    public ReplaceUserControl() {
        InitializeComponent();
        this.DataContext = this;
    }
    ....

    private int _progressBarMaximum;
    public int ProgressBarMaximum {
        get { return _progressBarMaximum; }
        set { _progressBarMaximum = value; RaisePropertyChanged("ProgressBarMaximum"); }
    }

    private int _progressBarCurrent;
    private int ProgressBarCurrent {
        get { return _progressBarCurrent; }
        set { _progressBarCurrent = value; RaisePropertyChanged("ProgressBarCurrent"); }
    }


    private void ReplaceTextInFiles() { //Called from Button_Click Handler
        ....

        ProgressBarMaximum = filesList.Count - 1;

        SearchReplaceWorker replaceWorker = new SearchReplaceWorker(); //The Work Horse
        replaceWorker.FileProcessed += new FileProcessedEventHandler(worker_FileProcessed); //Raised by Work Horse when each file is processed

        BackgroundWorker workerThread = new BackgroundWorker(); //The Background Worker Thread
        workerThread.DoWork += (o, e) => {
            replaceWorker.ReplaceTextInFiles(SearchText, ReplaceText, filesList, ReportFolderPath, MatchCase, MatchSubstring);
        };
        workerThread.RunWorkerAsync(); //Start the Background Thread Async
    }

    void worker_FileProcessed(object sender, EventArgs e) {
        ProgressBarCurrent = ProgressBarCurrent + 1; //Update the ProgressBar status
    }

当 ProgressBarCurrent 如上代码所示递增时,为什么 ProgressBar 不自行更新。

编辑: 为了在 UI 线程上处理 ProgressBar 更新代码,我将代码更改为使用 BackgroundWorker.ReportProgress(),如下所示。

用户控件的代码隐藏:

private void ReplaceTextInFiles() { //Called from Button_Click()
    if (!Directory.Exists(SearchFolderPath)) {
        MessageBox.Show("Invalid Directory Selected for Search");
        return;
    }

    if (!Directory.Exists(ReportFolderPath)) {
        MessageBox.Show("Invalid Directory Selected for Report File");
        return;
    }

    List<string> filesList = null;
    try {
        if (LookInSubFolders) {
            filesList = Directory.GetFiles(@SearchFolderPath, "*.dwg", SearchOption.AllDirectories).ToList();
        }
        else {
            filesList = Directory.GetFiles(@SearchFolderPath, "*.dwg", SearchOption.TopDirectoryOnly).ToList();
        }
    }
    catch (Exception ex) {
        MessageBox.Show("Error Occurred getting the files list. Contact Admin");
    }

    pgrSearch.Visibility = Visibility.Visible;
    ProgressBarMaximum = filesList.Count - 1;

    SearchReplaceWorker replaceWorker = new SearchReplaceWorker(); 

    BackgroundWorker workerThread = new BackgroundWorker(); 
    workerThread.WorkerReportsProgress = true;
    workerThread.ProgressChanged += (o, e) => { //This event handler gets called correctly.
        ProgressBarCurrent++; 
    };
    workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThread_RunWorkerCompleted);
    workerThread.DoWork += (o, e) => {
        replaceWorker.ReplaceTextInFiles(workerThread, SearchText, ReplaceText, filesList, ReportFolderPath, MatchCase, MatchSubstring);
    };
    workerThread.RunWorkerAsync(); 
}

BackgroundWorker:

public void ReplaceTextInFiles(BackgroundWorker workerThread, string searchText, string replaceText, List<string> filesList, string reportPath,
                                      bool MatchCase, bool MatchSubstring) {
    ...
    workerThread.ReportProgress(50);
}

ProgressBar 仍然不会自行更新。

【问题讨论】:

  • 我在类似问题上得到了一些帮助。 stackoverflow.com/questions/1890518/…
  • 哪里出错了?你确定 worker_FileProcessed 被调用了吗?
  • @ekholm,是的,我确实调试了代码,它正确地命中了 worker_FileProcessed。
  • 是否在设置器中调用了RaisePropertyChanged(放置调试点)?在 Visual Studio 的“输出”窗口中是否看到任何绑定错误?
  • 您在问题中的代码没有显示调用 BackgroundWorker.ReportProgress 也没有连接到 ProgressChanged。

标签: wpf wpf-4.0


【解决方案1】:

我使用您的初始代码创建了一个测试项目。过了一会儿,我发现您已将 ProgressBarCurrent 属性声明为 private。更改为公开后,它对我有用。所以似乎没有必要更新 UI 线程上的属性。读回更新后的属性值时,看起来像是在内部进行了 Dispatcher.Invoke 调用。

【讨论】:

  • 确实是个愚蠢的错误。 ProgressBarCurrent 被错误地声明为私有。我真的很感谢你付出的努力并找到了那个愚蠢的错误。
  • 在这种情况下,编译器警告会很好,虽然我意识到这不是微不足道的...... :)
猜你喜欢
  • 2014-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多