Home > Net >  Dispatcher.BeginInvoke(new...ProgressBarProcess.Value = 1 not showing?
Dispatcher.BeginInvoke(new...ProgressBarProcess.Value = 1 not showing?

Time:11-12

This is for Windows 10, Windows Application WPF .NET framework 4.7.2

I have code from an older windows form project (vs 2017 community) for a ProgressBar that worked fine (Windows Forms project). I have a wpf windows project now that works fine but I wanted to add a progress bar to the two buttons (Proccess and Insert buttons) click event because they take several seconds to complete and I want to see some progress. This project is for me only and it always runs inside visual studio (community 2019). I copied the old code to the new project but the progressbar does not show up or show progress. The code is in the buttonclick event in the old project as in the new one but no luck....I maybe missing something from the old project but I don't see what. I know about the "can not modify the UI from the calling thread" but I thought I used a different thread with Task.Factory.StartNew. There are a lot of posts/threads here for Dispatcher.BeginInvoke but I couldn't find one similar to mine ... one of them said that this approach was the wrong way to do it. I don't do MVVM stuff. I don't do windows programming C# very often so don't assume that I know what I'm doing....LOL. Any help to show the progressbar would be appreciated. A pointer on how to do it "right" also appreciated.Thanks. Here is the code for one of the buttons (ProcessButton_Click) its progressbar is named "ProgressBarProcess":

 private void ProcessButton_Click(object sender, RoutedEventArgs e)
    {
        if (targetBOMTextBox.Text.Length != 11)
        {
            MessageBox.Show("Target BOM part number missing or incorrect format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }

        Task.Factory.StartNew(() => ProcessButtonFunction());
    }

 private void ProcessButtonFunction()
        {
            ProgressBarProcess.Minimum = 1;
            ProgressBarProcess.Maximum = 5;
            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Visibility = Visibility.Visible; }));

            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 1; }));
            fillExcelLists();
            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 2; }));
            convertTofloatList();
            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 3; }));
            splitDesignatorList();
            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 4; }));
            fillRecordsList();
            Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 5; }));

            insertButton.IsEnabled = true;
            clearButton.IsEnabled = true;


        }



private void fillExcelLists()
    {
        ExcelAccess ExcelAccessOBJ = new ExcelAccess();

        //get part numbers from excel column to GlobalData.excelPartNoList
        ExcelAccessOBJ.ExcelReadColumn(partNoComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelPartNoList);

        //get quantities from excel column to GlobalData.excelQuantityList
        ExcelAccessOBJ.ExcelReadColumn(quantityComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelQuantityList);
       
        //get designators from excel column to GlobalData.excelDesignatorList
        ExcelAccessOBJ.ExcelReadColumn(designatorsComboBox.SelectedItem.ToString(), Convert.ToInt16(dataStartRowTextBox.Text), Convert.ToInt16(dataEndRowTextBox.Text), GlobalData.excelDesignatorList);

    }
 

 public class ExcelAccess
{
    public void ExcelReadColumn(string column, int rowStart, int rowEnd, List<String> saveData)
    {
        //set up excel stuff
        Microsoft.Office.Interop.Excel.Application ExcelObj = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(GlobalData.excelFilenameAndPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        Microsoft.Office.Interop.Excel.Sheets sheets = theWorkbook.Worksheets;
        Microsoft.Office.Interop.Excel.Range data_range;

        Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(1);      //first sheet

        //Read column
        for (int i = rowStart; i <= rowEnd; i  )
        {
            data_range = sheet.get_Range(column   i.ToString(), column   i.ToString());     //read part number from excel sheet

            //Convert cell value to string 
            string tempString = Convert.ToString(data_range.Cells.Value2);
            if (tempString != string.Empty)
            {
                saveData.Add(tempString);
            }
            
        }

        theWorkbook.Close();
        ExcelObj.Quit();

    }

}

CodePudding user response:

Stay on the dispatcher thread and await tasks that execute the long-running methods on background threads:

private async void ProcessButton_Click(object sender, RoutedEventArgs e)
{
    if (targetBOMTextBox.Text.Length != 11)
    {
        MessageBox.Show("Target BOM part number missing or incorrect format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        return;
    }

    ProgressBarProcess.Visibility = Visibility.Visible;
    ProgressBarProcess.Minimum = 1;
    ProgressBarProcess.Maximum = 5;
    ProgressBarProcess.Value = 1;
    await Task.Run(() => fillExcelLists());
    ProgressBarProcess.Value = 2;
    await Task.Run(() => convertTofloatList());
    ProgressBarProcess.Value = 3;
    await Task.Run(() => splitDesignatorList());
    ProgressBarProcess.Value = 4;
    await Task.Run(() => fillRecordsList());
    ProgressBarProcess.Value = 5;

    insertButton.IsEnabled = true;
    clearButton.IsEnabled = true;
}

No need to involve the dispatcher really.

CodePudding user response:

Here is what I end up doing and works. I wanna thanks everyone for their help. The main issue I had seems to be that I was accessing UI from where I wasn't supposed to. Also ProgressBarProcess.Minimum and ProgressBarProcess.Maximum don't seem to work as I read (Link), probably something I missed. Thanks again:

 private void ProcessButton_Click(object sender, RoutedEventArgs e)
    {
        if (targetBOMTextBox.Text.Length == 11)
        {
            GlobalData.TargetBOMpartNo = targetBOMTextBox.Text;

            GlobalData.partNoColumn = partNoComboBox.SelectedItem.ToString();
            GlobalData.quantityColumn = quantityComboBox.SelectedItem.ToString();
            GlobalData.designatorColumn = designatorsComboBox.SelectedItem.ToString();

            GlobalData.dataRowStart = Convert.ToInt16(dataStartRowTextBox.Text);
            GlobalData.dataRowEnd = Convert.ToInt16(dataEndRowTextBox.Text);

        }
        else
        {
            MessageBox.Show("Target BOM part number missing or incorrect format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }

        ProcessButton.IsEnabled = false;

        Task.Factory.StartNew(() => ProcessButtonFunction());
      
    }

 private void ProcessButtonFunction()
    {
        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Visibility = Visibility.Visible; }));

        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 10; }));
        fillExcelLists();
        convertTofloatList();
        splitDesignatorList();
        fillRecordsList();
        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 100; }));

        //insertButton.IsEnabled = true;    //this generates an exception do it like below
        Dispatcher.BeginInvoke(new Action(delegate () { insertButton.IsEnabled = true; }));

        //clearButton.IsEnabled = true;  //this generates an exception do it like below
        Dispatcher.BeginInvoke(new Action(delegate () { clearButton.IsEnabled = true; }));

        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Visibility = Visibility.Hidden; }));

    }

 private void fillExcelLists()
    {
        ExcelAccess ExcelAccessOBJ = new ExcelAccess();

        //get part numbers from excel column to GlobalData.excelPartNoList
        ExcelAccessOBJ.ExcelReadColumn(GlobalData.partNoColumn, GlobalData.dataRowStart, GlobalData.dataRowEnd, GlobalData.excelPartNoList);
        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 30; }));
        
        //get quantities from excel column to GlobalData.excelQuantityList
        ExcelAccessOBJ.ExcelReadColumn(GlobalData.quantityColumn, GlobalData.dataRowStart, GlobalData.dataRowEnd, GlobalData.excelQuantityList);
        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 60; }));

        //get designators from excel column to GlobalData.excelDesignatorList
        ExcelAccessOBJ.ExcelReadColumn(GlobalData.designatorColumn, GlobalData.dataRowStart, GlobalData.dataRowEnd, GlobalData.excelDesignatorList);
        Dispatcher.BeginInvoke(new Action(delegate () { ProgressBarProcess.Value = 90; }));

    }
  • Related