绑定到运行长进程的依赖对象的WPF ProgressBar更新
作者:互联网
我想将WPF ProgressBar的value属性绑定到在长时间运行的过程中更新的依赖项属性.如果从主线程调用了长时间运行的进程,则这将阻止UI(并因此禁止进度条)更新,直到该进程完成为止-从而阻止了显示该进程所需的进度.长时间运行的进程也无法通过旋转单独的线程来运行,因为无法将依赖项属性从其他线程更新为其所有者(即创建它的线程).
在下面的代码中,单击按钮后,长时间运行的进程将运行,并且进度条从完成时的0%跳到100%.相反,我希望能够单击该按钮并让进度条显示长期运行进度的进度(即,不仅在流程结束时从0%更新为100%,而且显示了平稳的进度).
MainWindow.xaml
<Window x:Class="ProgressBarTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<Button Width="200" Height="50" x:Name="btnRun" Click="btnRun_Click">Run Process</Button>
<ProgressBar Width="200" Height="20" x:Name="pbProgress" Minimum="0" Maximum="100" Value="{Binding Path=MyFoo.ProgressValue}"/>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Threading;
namespace ProgressBarTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public Foo MyFoo { get; set; }
public MainWindow()
{
MyFoo = new Foo();
InitializeComponent();
}
private void btnRun_Click(object sender, RoutedEventArgs e)
{
btnRun.IsEnabled = false;
MyFoo.LongRunningProcess(); // Since this runs on same thread as UI, progress bar does not update until the long running process completes.
btnRun.IsEnabled = true;
}
}
public class Foo : DependencyObject
{
public static readonly DependencyProperty ProgressValueProperty = DependencyProperty.Register("ProgressValue", typeof(double), typeof(Foo));
public double ProgressValue
{
get { return (double)GetValue(ProgressValueProperty); }
set
{
SetValue(ProgressValueProperty, value);
}
}
public Foo()
{
ProgressValue = 0;
}
public void LongRunningProcess()
{
do
{
ProgressValue += 1;
Thread.Sleep(30);
}
while (ProgressValue < 100);
}
}
}
附言我知道有一种方法可以通过将ProgressBar实例作为参数传递给长时间运行的进程来实现,以便它可以直接通过Dispatcher.Invoke更新它,但这不是我想要的.我想通过绑定到依赖项属性来更新进度条.
谢谢
肖恩
解决方法:
我会尝试比欣快更好.
您需要使用BackgroundWorker运行LongRunningProcess,该进程在另一个线程上运行该进程,然后使用ProgressChanged事件更新该属性.
// This event handler updates the progress bar.
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
MyFoo.ProgressValue = e.ProgressPercentage;
}
标签:multithreading,binding,wpf-controls,wpf,c 来源: https://codeday.me/bug/20191023/1915359.html