我想创建一个进度条。我设置了进度条的值+ =一个值(比如+ = 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;
}
答案 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);
}