I'm using C # WPF.
I'm trying to figure out if there's a way to update the XAML elements without having to use the Refresh()
method that you see in the following code.
Now I am encasing the codes related to the C# doPlay()
method that is launched inside the MainWindow through a thread and the XAML code.
Can anyone suggest a way to update progress bars without having to use the Refresh()
method?
private void doPlay()
{
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Red"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Blue"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Yellow"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Cyan"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Black"));
Transfers.Add(new Transfer(Utils.RandomString(6), Utils.RandomString(6), Transfer.Type_t.download, "Brown"));
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.ItemsSource = Transfers;
}));
Random rnd = new Random();
for (var i = 0; i < 100 * Transfers.Count; i++)
{
var next = rnd.Next(0, Transfers.Count);
mre.WaitOne();
int index = next;
if (Transfers[index].CurrentStep < 100)
{
Thread.Sleep(100);
Transfers[index].CurrentStep++;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.Items.Refresh();
}));
}
else i--;
}
}
The XAML relative code:
<UniformGrid x:Name="DownLeftPanel" Grid.Column="2" Grid.Row="2">
<ListBox x:Name="TransfersXAML" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Transfers}">
<ListBox.ItemTemplate>
<DataTemplate>
<ProgressBar Height="30" Minimum="0" Maximum="{Binding NSteps}"
Value="{Binding CurrentStep}" Foreground="{Binding Color}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Get info" Click="GetTransferInfoClick" />
<MenuItem Header="Cancel" Click="CancelTransferClick" />
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</UniformGrid>
I tried to simply remove the Action from BeginInvoke, but in this way the bars are no longer displayed, that is, removing these instructions from the first posted code:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
TransfersXAML.Items.Refresh();
}));
This question is related to the following one: Network threads blocking the GUI, in particular, referring to the comments below the question itself.
See Question&Answers more detail:
os