user3559120
user3559120

Reputation: 11

How to display set of labels one after the other in c# wpf window?

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

Answers (2)

Sandesh
Sandesh

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

Dan
Dan

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

Related Questions