Implementing a pause in WPF

北城余情 提交于 2019-12-02 10:37:20

问题


Here you have a simple WPF program:

<!-- Updater.xaml -->
<Window x:Class="Update.Updater"
        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}}">
    <Grid>
        <StackPanel>
            <Button Click="Button_Click" Height="50"></Button>
            <Label Content="{Binding Label1Text}" Height="50"></Label>
            <Label Content="{Binding Label2Text}" Height="50"></Label>
        </StackPanel>
    </Grid>
</Window>

// Updater.xaml.cs
using System.Threading;
using System.Windows;

namespace Update
{
    public partial class Updater : Window
    {
        public Updater()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Label1Text = "It is coming...";
            Thread.Sleep(3000);
            Label2Text = "It is here!";
        }

        public string Label1Text
        {
            get { return (string)GetValue(CategoryProperty); }
            set { SetValue(CategoryProperty, value); }
        }

        static readonly DependencyProperty CategoryProperty = DependencyProperty.Register("Label1Text", typeof(string), typeof(Updater));

        public string Label2Text
        {
            get { return (string)GetValue(Label2TextProperty); }
            set { SetValue(Label2TextProperty, value); }
        }

        static readonly DependencyProperty Label2TextProperty = DependencyProperty.Register("Label2Text", typeof(string), typeof(Updater));
    }
}

The intention is that when you click the button, the first label displays It is coming.... Then the program sleeps for 3 seconds, and finally the second label displays It is here!. However, the naïve implementation below doesn't work. If you run it and click the button the following happens: The program sleeps for 3 seconds, and then the two label texts are displayed simultaneously. Do you know how to correct the program so that it does as intended?


回答1:


Button_Click is invoked by the UI thread, and you should not do anything requiring more than a few miliseconds in it, let alone sleeping for 3 seconds. Messages are not processed during that time, your interface is unresponsive, and your application is considered "hung" by the system.

So, that long processing task should be handled by another thread.

Something like that (untested):

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Label1Text = "It is coming...";

        var backgroundWorker = new BackgroundWorker();

        backgroundWorker.DoWork += (s,e) => {
          Thread.Sleep(3000);
        }

        backgroundWorker.RunWorkerCompleted += (s,e) => {
          Label2Text = "It is here!";
        }

        backgroundWorker.RunWorkerAsync();
    }

Links:

BackgroundWorker

Build More Responsive Apps With The Dispatcher




回答2:


Try this:

label1.Content = "waiting...";

label1.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
   {

        label1.UpdateLayout();
    }));

System.Threading.Thread.Sleep(3000);
label1.Content = "done!";



回答3:


You can use a storyboard and keyframe animation to do that.

http://msdn.microsoft.com/en-us/library/ms742868.aspx

There's a good example in here -

http://msdn.microsoft.com/en-us/library/system.windows.media.animation.stringanimationusingkeyframes.aspx

<Button Name="myAnimatedButton" Margin="200"
  FontSize="16pt" FontFamily="Verdana">Some Text
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <StringAnimationUsingKeyFrames 
            Storyboard.TargetName="myAnimatedButton" Storyboard.TargetProperty="(Button.Content)"
            Duration="0:0:8" FillBehavior="HoldEnd">

            <!-- All the key frames below are DiscreteStringKeyFrames. Discrete key frames create 
            sudden "jumps" between values (no interpolation). Only discrete key frames can be used 
            for String key frame animations. -->
            <DiscreteStringKeyFrame Value="" KeyTime="0:0:0" />
            <DiscreteStringKeyFrame Value="A" KeyTime="0:0:1" />
            <DiscreteStringKeyFrame Value="An" KeyTime="0:0:1.5" />
            <DiscreteStringKeyFrame Value="Ani" KeyTime="0:0:2" />
            <DiscreteStringKeyFrame Value="Anim" KeyTime="0:0:2.5" />
            <DiscreteStringKeyFrame Value="Anima" KeyTime="0:0:3" />
            <DiscreteStringKeyFrame Value="Animat" KeyTime="0:0:3.5" />
            <DiscreteStringKeyFrame Value="Animate" KeyTime="0:0:4" />
            <DiscreteStringKeyFrame Value="Animated" KeyTime="0:0:4.5" />
            <DiscreteStringKeyFrame Value="Animated " KeyTime="0:0:5" />
            <DiscreteStringKeyFrame Value="Animated T" KeyTime="0:0:5.5" />
            <DiscreteStringKeyFrame Value="Animated Te" KeyTime="0:0:6" />
            <DiscreteStringKeyFrame Value="Animated Tex" KeyTime="0:0:6.5" />
            <DiscreteStringKeyFrame Value="Animated Text" KeyTime="0:0:7" />
          </StringAnimationUsingKeyFrames>              
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger> 
  </Button.Triggers>
</Button>


来源:https://stackoverflow.com/questions/10383116/implementing-a-pause-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!