简体   繁体   中英

C# WFP Indeterminate Progress Bar to Animate

I'm fairly new to C# WPF and am needing help trying to have my indeterminate progress bar animate while my main code continues to run. I have researched and tried so many different threading methods and background workers, etc...but nothing seems to do the trick. The code below is the closest I have come, and I can actually see the progress bar start to animate and my main code continue to run, but then I get the exception "The calling thread cannot access this object because a different thread owns it." I greatly appreciate any insight on how I can accomplish this!

 public partial class MainWindow : Window
{

    public MainWindow()
    {
       InitializeComponent();
    }

    [STAThread]
    private async void cmsServerConnect(object sender, RoutedEventArgs e)
    {
        Login form = new Login();
        form.ShowDialog();

        if (form.cancelClicked == true && form.enter_Pressed == false)
        {
            return;
        }

        //Create new thread to have indeterminate progress bar run on
        //Set new thread appartmentstate to STA
        //Start thread
        Connect_Progress progress = new Connect_Progress();
        Thread t = new Thread(() => progress.Show());
        t.SetApartmentState(ApartmentState.STA);
        t.Start();

        //Using  async at method declaration
        //await is allowing the UI to continue updating while running the task connection.cmsConnect()
        Ribbon_Buttons connection = new Ribbon_Buttons();
        int connected = await Task.Run(() => connection.cmsConnect(form.id, form.Pword));

        if (connected == 2)
        {
            BitmapImage image = new BitmapImage();
            image.BeginInit();
                image.UriSource = new Uri("pack://application:,,,/Images/Circle_Green.png");
            image.EndInit();

            this.Ribbon_Button_ACM12_Connection.SmallImageSource = image;
            this.Ribbon_Button_ACM12_Connection.Label = "Connected";
        }

        t.Abort();

        this.Activate();
        this.Topmost = true;
        this.Topmost = false;
        this.Focus();
    }

You should use background worker,

xaml

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <ProgressBar x:Name="myProgressBar" Width="400" Grid.Row="0" Height="30" />
    <Button x:Name="myButton" Width="200" Height="30" Grid.Row="1" Click="myButton_Click" Content="Click Me" />
</Grid>

c#

 private readonly BackgroundWorker worker = new BackgroundWorker();

    public MainWindow()
    {
        InitializeComponent();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    }
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            Dispatcher.BeginInvoke((Action)(() =>
            {
                myProgressBar.Value = i;
            }));
            Thread.Sleep(100);
        }
    }

    private void worker_RunWorkerCompleted(object sender,
                                           RunWorkerCompletedEventArgs e)
    {
        myProgressBar.Value = 100;
    }
    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        worker.RunWorkerAsync();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM