在WPF中使用BackgroundWorker更新UI [英] Updating UI with BackgroundWorker in WPF

查看:411
本文介绍了在WPF中使用BackgroundWorker更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在编写一个简单的WPF 3.5应用程序,该应用程序利用SharePoint COM来调用SharePoint网站并生成组和用户信息.由于此过程需要一段时间,因此我想在生成组时显示一个ProgressBar.所需的过程如下:

I am currently writing a simple WPF 3.5 application that utilizes the SharePoint COM to make calls to SharePoint sites and generate Group and User information. Since this process takes awhile I want to show a ProgressBar while the groups are being generated. The desired process is as follows:

  1. 用户输入网址并单击按钮以获取站点数据.
  2. ProgressBar开始动画
  3. 生成组并将名称添加到ListView
  4. 完成进度栏动画结束

我遇到的问题是UI从未更新. ProgressBar或ListView均未进行任何更改.如果有人对下面的代码有任何帮助的想法,将不胜感激.

The problem I am running into is that the UI is never updated. Neither the ProgressBar or the ListView makes any changes. If anyone has any ideas to help with the code below it would be greatly appreciated.

private void GetGroupsAndUsersButton_Click(object sender, RoutedEventArgs e)
{
    siteUrl = "";

    if (SiteURLTextBox.Text.Length > 0)
    {
        FetchDataProgressBar.IsIndeterminate = true;

        mWorker = new BackgroundWorker();
        mWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
        mWorker.WorkerSupportsCancellation = true;
        mWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        mWorker.RunWorkerAsync();
    }
    else
    {
        System.Windows.MessageBox.Show("Please enter a URL for the SharePoint site you wish to retrieve data");
    }
}

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    siteUrl = SiteURLTextBox.Text;
    GroupListView.ItemsSource = null;

    try
    {
        using (SPSite site = new SPSite(siteUrl))
        {
            SPWeb web = site.OpenWeb();
            SPGroupCollection collGroups = web.SiteGroups;
            if (GroupNames == null)
                GroupNames = new List<string>();

            foreach (SPGroup oGroup in collGroups)
            {
                GroupListView.Items.Add(new ListViewItem() { Content = oGroup.Name });
            }

            foreach (ListViewItem item in GroupListView.Items)
            {
                item.MouseLeftButtonUp += item_MouseLeftButtonUp;
            }
        }
    }
    catch (Exception ex)
    {
        System.Windows.MessageBox.Show("Unable to locate a SharePoint site at: " + siteUrl);
    }
}

private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    FetchDataProgressBar.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
    new Action(
        delegate()
        {
            FetchDataProgressBar.IsIndeterminate = false;
        }
        ));
}

推荐答案

首先,您需要支持ProgressChanged事件. 将BackgroundWorker初始化更新为:

At first you need to support ProgressChanged events. Update your BackgroundWorker initialization to:

GroupListView.ItemSource = null;
mWorker = new BackgroundWorker();
mWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
mWorker.WorkerSupportsCancellation = true;
mWorker.WorkerReportsProgress = true;
mWorker.ProgressChanged += OnProgressChanged;
mWorker.RunWorkerCompleted +=
        new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
mWorker.RunWorkerAsync(SiteURLTextBox.Text);

此后,您必须添加OnProgressChanged处理程序:

After that you have to add a OnProgressChanged handler:

private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
    FetchDataProgressBar.Value = e.ProgressPercentage;
    ListViewItem toAdd = (ListViewItem)e.UserState;
    toAdd.MouseLeftButtonUp += item_MouseLeftButtonUp;
    GroupListView.Items.Add(toAdd);
}

因此,您必须更改DoWork:

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker)sender;            
    try
    {
        using (SPSite site = new SPSite((String)e.Argument))
        {
            SPWeb web = site.OpenWeb();
            SPGroupCollection collGroups = web.SiteGroups;
            if(GroupNames == null)
                GroupNames = new List<string>();
            int added = 0;
            foreach(SPGroup oGroup in collGroups)
            {
                added++;
                ListViewItem tmp = new ListViewItem() {
                    Content = oGroup.Name
                };
                worker.ReportProgress((added * 100)/collGroups.Count,tmp);
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Unable to locate a SharePoint site at: " + siteUrl);
    }
}

那是因为不允许您更改DoWork上的GUI.

That's because you're not allowed to change GUI on DoWork.

之后,每个ListViewItem分别添加到您的ListView中.我还建议将您的URL作为参数传递给RunWorkerAsync.

After that, each ListViewItem is added separately to your ListView. I would also recommend, that your URL is passed as an argument to RunWorkerAsync.

修改:将百分比添加到OnProgressChanged.

这篇关于在WPF中使用BackgroundWorker更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆