Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 实时更新WPF中的进度条_.net_Wpf_Vsto - Fatal编程技术网

.net 实时更新WPF中的进度条

.net 实时更新WPF中的进度条,.net,wpf,vsto,.net,Wpf,Vsto,我使用下面的代码在WPF VSTO应用程序中实时更新了一个进度条 但是,有一个问题,行object[,]obj=GetOutput(objInput)抛出一个错误,说明它无法访问此对象,因为它位于不同的线程中。当我将其置于Dispatch.Invoke下时,我的进度条不会实时更新。有人能帮我吗 private BackgroundWorker backgroundWorker1 = new BackgroundWorker(); private object[,] GetOutput(obje

我使用下面的代码在WPF VSTO应用程序中实时更新了一个进度条 但是,有一个问题,行
object[,]obj=GetOutput(objInput)抛出一个错误,说明它无法访问此对象,因为它位于不同的线程中。当我将其置于Dispatch.Invoke下时,我的进度条不会实时更新。有人能帮我吗

private BackgroundWorker backgroundWorker1 = new BackgroundWorker();

private object[,] GetOutput(object[,] obj)
{
    object[,] objOutput = null;
    if (rdUpper.IsChecked == true) //--- This UI element is causing the issue
        objOutput = t1.ConvertCase(obj);

    return objOutput;
}

private void btnTest_Click(object sender, RoutedEventArgs e)
{
    t1.OnProgressUpdate += t1_OnProgressUpdate;
    pb.Maximum = 30;
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.RunWorkerAsync();
}

 private void t1_OnProgressUpdate(int value)
 {
    Dispatcher.Invoke((Action)delegate
    {
       pb.Value = value;
    });
  }

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  {
            try
            {
                Excel.Range SelectedRange = Globals.ThisAddIn.Application.Selection as Excel.Range;

                foreach (Excel.Range rngArea in SelectedRange.Areas)
                {
                    objInput = Common.GetObject(SelectedRange);
                    object[,] obj =  GetOutput(objInput); //-- This throws an error

                  //  rngArea.Value = obj;
                    backgroundWorker1.CancelAsync();
                }

            }
            catch(Exception ex)
            {
                throw;
            }
        }
    }


    class testClass
    {
        public delegate void ProgressUpdate(int value);
        public event ProgressUpdate OnProgressUpdate;
        public object[,] ConvertCase(object[,] objInput)
        {
            object[,] objOutput = (object[,])objInput.Clone();

            for (int row = objInput.GetLowerBound(0); row <= objInput.GetUpperBound(0); row++)
            {
                for (int col = objInput.GetLowerBound(1); col <= objInput.GetUpperBound(1); col++)
                {
                    objOutput[row, col] = objInput[row, col] is null ? null : objInput[row, col].ToString().ToUpper();
                }

                Thread.Sleep(200); // To check and see the real time progress update
                if (OnProgressUpdate != null)
                {        
                    OnProgressUpdate(row);
                }

            }
            return objOutput;
        }
    }
private BackgroundWorker backgroundWorker1=new BackgroundWorker();
私有对象[,]GetOutput(对象[,]obj)
{
对象[,]objOutput=null;
如果(rdUpper.IsChecked==true)/---此UI元素导致问题
objOutput=t1.ConvertCase(obj);
返回对象输出;
}
私有void btnTest\u单击(对象发送者,路由目标e)
{
t1.OnProgressUpdate+=t1_OnProgressUpdate;
pb.最大值=30;
backgroundWorker1.WorkerReportsProgress=true;
backgroundWorker1.WorkerSupportsScanCellation=true;
backgroundWorker1.DoWork+=backgroundWorker1_DoWork;
backgroundWorker1.RunWorkerAsync();
}
私有void t1_OnProgressUpdate(int值)
{
Dispatcher.Invoke((操作)委托
{
pb.价值=价值;
});
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
尝试
{
Excel.Range SelectedRange=Globals.ThisAddIn.Application.Selection作为Excel.Range;
foreach(选定范围区域中的Excel.Range rngArea)
{
objInput=Common.GetObject(SelectedRange);
object[,]obj=GetOutput(objInput);//--这会引发一个错误
//rngArea.Value=obj;
backgroundWorker1.CancelAsync();
}
}
捕获(例外情况除外)
{
投
}
}
}
类testClass
{
公共委托无效进程更新(int值);
公共事件进展更新;
公共对象[,]ConvertCase(对象[,]objInput)
{
对象[,]objOutput=(对象[,])objInput.Clone();

对于(int row=objInput.GetLowerBound(0);row您正在使用
BackgroundWorker
false。您对ProgressUpdate的调用是从后台线程调用的

您必须从
BackgroundWorker
订阅
ProgressChanged
-事件。在这种方法中,您可以在UI线程上执行操作

请看下面的代码:

private void Button1_Click(object sender, RoutedEventArgs e)
{
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.WorkerSupportsCancellation = true;
    backgroundWorker.DoWork += BackgroundWorkerOnDoWork;
    backgroundWorker.ProgressChanged += BackgroundWorkerOnProgressChanged;
    backgroundWorker.RunWorkerAsync(t1);
}

private void BackgroundWorkerOnProgressChanged(object sender, ProgressChangedEventArgs e)
{
   // This method will be called if in the DoWork-Method a call to ReportProgress is made. 
   // You can access the provided data with:
   object data = e.UserState;
}

private void BackgroundWorkerOnDoWork(object sender, DoWorkEventArgs e)
{
    testClass t1 = (testClass) e.Argument;

    // Your async-logic here. Everything here will be executed in a Thread
    // If you want to update the UI you have to do the following:
    ((BackgroundWorker)sender).ReportProgress(0, "OBJECT-TO-PASS-TO-THE-UI-THREAD");

}

由于无法访问后台线程上控件或其他UI元素的属性,因此在启动后台工作程序之前,应检查
IsChecked
属性是否为
true

将值存储在传递给
RunWorkerAsync
方法的
bool
变量中:

private object[,] GetOutput(object[,] obj, bool isChecked)
{
    object[,] objOutput = null;
    if (isChecked)
        objOutput = t1.ConvertCase(obj);

    return objOutput;
}

private void btnTest_Click(object sender, RoutedEventArgs e)
{
    t1.OnProgressUpdate += t1_OnProgressUpdate;
    pb.Maximum = 30;

    bool isChecked = rdUpper.IsChecked == true;

    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.RunWorkerAsync(isChecked);
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Excel.Range SelectedRange = Globals.ThisAddIn.Application.Selection as Excel.Range;

    foreach (Excel.Range rngArea in SelectedRange.Areas)
    {
        objInput = Common.GetObject(SelectedRange);
        bool isChecked = (bool)e.Argument;
        object[,] obj = GetOutput(objInput, isChecked);

        //  rngArea.Value = obj;
        backgroundWorker1.CancelAsync();
    }
}

在GetOutput方法中,我发现了另一个问题,我正在访问导致问题的UI元素,如果(rdUpper.IsChecked==true)(我编辑了代码)选中此项。除UI线程外,其他线程也不能直接访问UI元素。@SamK:您不应该在
DoWork
中访问UI元素,您的
GetOutput
做什么?@mm8我在UI上有几个单选按钮,根据选择,GetOutput将不同的枚举传递给TestClass并获取output@SamK:你应该将其包含在问题中。但无论如何,您无法访问后台线程上的单选按钮而不获得异常。如何在BackgroundWorkRondWork方法中获取ProgressPercentage?您必须计算该值,然后才能将其传递给ProgressChanged方法如何从TestClas调用ProgressChanged我在类上有一个委托和事件,我可以更新它。我在这里有点困惑。