Reputation: 11
I have a wpf window which has four labels m1,m2,m3,m4.When I click a button in the window,all the four labels should be displayed one after the other.But I'm getting all the labels displayed at once which shouldn't happen.
private void button_Click(object sender, RoutedEventArgs e)
{
m1.Content = DateTime.Now.ToString("HH:mm:ss") + " Establishing Connection";
//some code
m2.Content = DateTime.Now.ToString("HH:mm:ss") + " Connected";
//some code
m3.Content = DateTime.Now.ToString("HH:mm:ss") + " Processing";
//some code
m4.Content = DateTime.Now.ToString("HH:mm:ss") + " Finished";
}
After running the application the window shows the following all labels displayed at once not one after the other as per the time
10:14:20 Establishing Connection
10:14:24 Connected
10:14:26 Processing
10:14:30 Finished
Upvotes: 0
Views: 857
Reputation: 3004
What you can do is after setting the Content
of the Label
you can toggle the Visibility
of the Label
so that instead of getting all the Label
at once you would get it one by one. As @Dan suggested use a StackPanel
to arrange the Label
. Also take care of one important point that the UI thread is updated after each operation.
Below is the sample code used by me.
MainWindow.xaml
<StackPanel>
<Button Content="Testing" Click="Button_Click" />
<Label Name="m1" Visibility="Hidden" />
<Label Name="m2" Visibility="Hidden" />
<Label Name="m3" Visibility="Hidden" />
<Label Name="m4" Visibility="Hidden" />
</StackPanel>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent ();
}
private async void Button_Click (object sender, RoutedEventArgs e)
{
m1.Content = DateTime.Now.ToString ("HH:mm:ss") + " Establishing Connection";
m1.Visibility = Visibility.Visible;
await Task.Run (() => Thread.Sleep (2000));
m2.Content = DateTime.Now.ToString ("HH:mm:ss") + " Connected";
m2.Visibility = Visibility.Visible;
await Task.Run (() => Thread.Sleep (2000));
m3.Content = DateTime.Now.ToString ("HH:mm:ss") + " Processing";
m3.Visibility = Visibility.Visible;
await Task.Run (() => Thread.Sleep (2000));
m4.Content = DateTime.Now.ToString ("HH:mm:ss") + " Finished";
m4.Visibility = Visibility.Visible;
await Task.Run (() => Thread.Sleep (2000));
}
}
I hope it helps. You can also use BackgroundWorker
to avoid UI freezing.
Below is the code using BackgroundWorker
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private readonly BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
m1.Visibility = Visibility.Hidden;
m2.Visibility = Visibility.Hidden;
m3.Visibility = Visibility.Hidden;
m4.Visibility = Visibility.Hidden;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher.Invoke(() =>
{
m1.Content = DateTime.Now.ToString("HH:mm:ss") + " Establishing Connection";
m1.Visibility = Visibility.Visible;
});
Thread.Sleep(2000);//your code
Dispatcher.Invoke(() =>
{
m2.Content = DateTime.Now.ToString("HH:mm:ss") + " Connected";
m2.Visibility = Visibility.Visible;
});
Thread.Sleep(2000);//your code
Dispatcher.Invoke(() =>
{
m3.Content = DateTime.Now.ToString("HH:mm:ss") + " Processing";
m3.Visibility = Visibility.Visible;
});
Thread.Sleep(2000);//your code
Dispatcher.Invoke(() =>
{
m4.Content = DateTime.Now.ToString("HH:mm:ss") + " Finished";
m4.Visibility = Visibility.Visible;
});
Thread.Sleep(2000);//your code
}
}
Upvotes: 1
Reputation: 754
The container you are looking for is called a StackPanel, it will automatically place any elements inside it one after another.
Example
<StackPanel Orientation="Vertical">
<Label Name="m1"/>
<Label Name="m2"/>
<Label Name="m3"/>
<Label Name="m4"/>
</StackPanel>
Upvotes: 1