如何在方法中使用值为+ =的进度条?

时间:2016-09-01 12:53:54

标签: c# wpf progress-bar

我想创建一个进度条。我设置了进度条的值+ =一个值(比如+ = 5)。在开始时,值= 0。

XAML代码。

<ProgressBar x:Name="pgbStatus" Minimum="0" Maximum="100" />

我想像这样设置进度条的值:

pgbStatus.Value += 10;

在这个方法中有很多行像这样设置值。

但是如果我启动程序,进度条会显示0值(=空),最后显示100值(=完整)。

为什么进度条没有显示我之间的步骤?

我的方法看起来像(如果消息框显示,进度条显示100 =已满):

public void Method() {
    //do something
    pgbStatus.Value += 10;
    //do something
    pgbStatus.Value += 10;
    //do something
    MessageBox.Show("Finished");
    pgbStatus.Value = 0;
}

5 个答案:

答案 0 :(得分:1)

Ui线程没有时间来更新UI,所以你需要给UI线程留出时间进行UI更新。为此,您必须以异步方式完成工作。你可以使用await和async。我已按以下方式更新您的方法:

    public async void Method()
    {
        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        //do something
        await Task.Delay(1000);
        pgbStatus.Value += 10;

        MessageBox.Show("Finished");
        pgbStatus.Value = 0;
    }

您可以放置​​代码

,而不是Task.delay(1000)

答案 1 :(得分:1)

首先,我们需要创建一个DataBinding。在xaml中:

$json = '{
"Token" : "xxx-xxx-xxx",
"ID": "1",
"Recipients": [
    {
        "Recipient_ID": "XX",
        "From_Name": "XXX",
        "From_Email": "XXX",
        "To_Name": "XXX",
        "To_Email": "XXX",
        "Subject": "XXX",
        "Message": "XXX",
        "Attachments": [
            {
                "File_Name": "XXX",
                "File_Path": "XXX"
            }
        ]
    }
]
}';

现在我们为绑定创建一个类:

<ProgressBar x:Name="pgbStatus" Minimum="0" Maximum="100" Value="{Binding Path=ProgBarValue}"/>

在主窗口后面的代码中,我们将类的实例与绑定关联起来:

public class AuxBindings : INotifyPropertyChanged
{
    public AuxBindings()
    {
        ProgBarValue=0;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    private int progBarValue;
    public int ProgBarValue
    {
        get
        {
            return progBarValue;
        }
        set
        {
            progBarValue = value;
            NotifyPropertyChanged();
        }
    }
}

现在我们要做的就是为执行创建一个新线程,并且需要进行所有值修改,只需要更改属性的值:

AuxBindings a = new AuxBindings();

public MainWindow()
{
    InitializeComponent();
    pgbStatus.DataContext=a;
}

答案 2 :(得分:0)

当程序运行时,这将在一个步骤上执行。 要解决这个问题,您应该使用全局int变量随时保存进度百分比(如int percent = 0)并在代码中更新它。

然后,您应该使用一个计时器(如Timer MyTimer)来更新指定时间间隔内的进度值(例如每100毫秒),并在每个时间间隔内使用:(将其放入MyTimer_Tick事件中)

progressbar.Value = percent.
if(percent>=100)
{
    MessageBox.Show("Finished!");
    MyTimer.Enabled = false;
}

通过这个,程序运行两个线程并更新进度值。

执行此操作并查看结果。

我希望这会有用。

答案 3 :(得分:0)

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTaskOnUiThread"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ProgressBarTaskOnUiThread" Height="100" Width="300"
    ContentRendered="Window_ContentRendered">
<Grid Margin="20">
    <ProgressBar Minimum="0" Maximum="100" Name="pbStatus" />
</Grid>

            private void This_is_Your_Button_Click_EVENT(object sender, EventArgs e)
            {
                    BackgroundWorker worker = new BackgroundWorker();
                    worker.WorkerReportsProgress = true;
                    worker.DoWork += worker_DoWork;
                    worker.ProgressChanged += worker_ProgressChanged;

                    worker.RunWorkerAsync();
            }
            void worker_DoWork(object sender, DoWorkEventArgs e)
            {
                    for(int i = 0; i < 100; i++)
                    {
                            (sender as BackgroundWorker).ReportProgress(i);
                            Thread.Sleep(100);
                    }
            }

            void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                    pbStatus.Value = e.ProgressPercentage;
            }

答案 4 :(得分:0)

我想还有一个答案不会受到伤害......

在按钮点击处理程序中,运行您的&#34;方法&#34;在另一个线程上。当您需要更新进度条时,使用它的Dispatcher来增加值(调度程序在UI线程上运行代码)。

点击事件处理程序:

private async void btnMethod_Click(object sender, RoutedEventArgs e)
{
    pgbStatus.Value = 0;
    await Task.Run((Action)Method);
    MessageBox.Show("Finished");
    pgbStatus.Value = 0;
}

更新的方法,方法:

public void Method()
{
    System.Threading.Thread.Sleep(500); // do something
    pgbStatus.Dispatcher.Invoke(() => pgbStatus.Value += 10);
    System.Threading.Thread.Sleep(500); // do something
    pgbStatus.Dispatcher.Invoke(() => pgbStatus.Value += 10);
    System.Threading.Thread.Sleep(500); // do something
    pgbStatus.Dispatcher.Invoke(() => pgbStatus.Value += 60);
    System.Threading.Thread.Sleep(500); // do something
    pgbStatus.Dispatcher.Invoke(() => pgbStatus.Value += 10);
    System.Threading.Thread.Sleep(500); // do something
    pgbStatus.Dispatcher.Invoke(() => pgbStatus.Value += 10);
}