Je souhaite lier la propriété value d'un ProgressBar WPF à une propriété de dépendance mise à jour pendant un processus de longue durée. Si le processus en cours d'exécution est appelé à partir du thread principal, cela bloque l'interface utilisateur (et donc le ProgressBar) de la mise à jour jusqu'à ce que le processus se termine, empêchant la progression désirée à travers le processus affiché. Le processus de longue durée ne peut pas non plus être exécuté en faisant tourner un thread séparé car il n'est pas possible de mettre à jour une propriété de dépendance d'un thread différent à son propriétaire (c'est-à-dire le thread sur lequel il a été créé).Mise à jour de WPF ProgressBar liée à un objet de dépendance exécutant un long processus
Dans le code ci-dessous, lorsque le bouton est cliqué, le processus de longue durée s'exécute et la barre de progression saute de 0% à 100% lorsqu'elle se termine. Au lieu de cela, je veux pouvoir cliquer sur le bouton et faire en sorte que la barre de progression montre la progression à travers la progression en cours (non seulement mise à jour de 0% à 100% lorsque le processus se termine mais montre une progression régulière).
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);
}
}
}
post-scriptum Je sais que je peux faire cela en passant l'instance de ProgressBar comme argument au processus de longue durée afin qu'elle puisse le mettre à jour directement via Dispatcher.Invoke, mais ce n'est pas ce que je veux. Je souhaite que la barre de progression soit mise à jour via la liaison à une propriété de dépendance.
Merci
Sean
Merci Eduardo. Cependant, je ne suis pas sûr de savoir comment cela fonctionnerait pour résoudre mon problème. À la suite de l'extrait ci-dessus: L'instance MyFoo doit déclencher l'événement ci-dessus (ProgressChanged) sur le travailleur d'arrière-plan, puis l'événement met à jour la valeur de la propriété MyFoo.ProgressValue? L'instance MyFoo peut bien sûr mettre à jour sa propre propriété (comme dans le code que j'ai montré), le problème est que le ProgressBar de l'interface utilisateur ne se met pas à jour. – sean