I have created a demo, that will hopefully demonstrate the problem I have been having for the last couple of days.
I have created a simple class named Data Supplier with a single public static method named GenerateRandomInt() this is to simulate having a process which might take some time. The code for the aforementioned class can be found below:
class DataSupplier
{
public static int GenerateRandomInt()
{
Random rnd = new Random();
Thread.Sleep(1000);
return rnd.Next();
}
}
My MainWindow simple contains a ScrollViewer with StackPanel embedded inside it named stackPanel1 , also a Button named button1 the XAML for this is shown below:
<Window x:Class="ThreadingDemo.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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<ScrollViewer>
<StackPanel Name="stackPanel1" />
</ScrollViewer>
<Button Grid.Row="1"
Name="button1"
Content="Generate 10 Labels"
Click="button1_Click" />
</Grid>
</Window>
What I want to achieve, is when I click button1 10 labels are generated, which display a random number using the static DataSupplier.GetRandomInt() method. However I want them to be displayed one by one, i.e. as soon as they are individually created. The codebehind for my MainWindow is shown below:
public partial class MainWindow : Window
{
private BackgroundWorker worker;
public MainWindow()
{
InitializeComponent();
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.IsEnabled = true;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
this.Dispatcher.Invoke((Action)(() =>
{
for (int i = 1; i <= 10; i++)
{
//create a new label, and set it's content to a randomly generated number
Label lbl = new Label();
lbl.Content = DataSupplier.GenerateRandomInt();
//add this label to stackPanel1
stackPanel1.Children.Add(lbl);
}
}));
}
private void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
worker.RunWorkerAsync();
}
}
However, what is happening is that nothing visually appears until all 10 of my randomly generated labels have been added to stackPanel1.
Is there anyway I can program this so that each label appears as each one is created? Whilst also ensuring that my UI remains responsive?