在以下示例中,我该如何获得:
正在完成工作,而不是 工作完成后?
XAML:
<Window x:Class="TestIsEnabled8938.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Margin="10" HorizontalAlignment="Left">
<Button x:Name="Button_Refresh"
HorizontalAlignment="Left"
DockPanel.Dock="Top"
Content="Refresh"
Click="Button_Refresh_Click"
Height="25"
Width="200"/>
<TextBlock x:Name="Message" Text="Button is ready to click."/>
</StackPanel>
</Window>
代码隐藏:
using System.Windows;
using System.Threading;
namespace TestIsEnabled8938
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Refresh_Click(object sender, RoutedEventArgs e)
{
Message.Text = "working...";
Button_Refresh.IsEnabled = false;
//do work
Thread.Sleep(2000);
Message.Text = "Button is ready to click again.";
Button_Refresh.IsEnabled = true;
}
}
}
Dispatcher.Invoke(new Action(() => { Message.Text = "working..."; }));
Dispatcher.Invoke(new Action(() => { Button_Refresh.IsEnabled = false; }));
感谢Heinzi,这段代码有效:
using System.Windows;
using System.Threading;
using System.ComponentModel;
namespace TestIsEnabled8938
{
public partial class Window1 : Window
{
BackgroundWorker backgroundWorker;
public Window1()
{
InitializeComponent();
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (sender, args) =>
{
Thread.Sleep(3000);
};
backgroundWorker.RunWorkerCompleted += (sender, args) =>
{
Message.Text = "button is ready to click again";
Button_Refresh.IsEnabled = true;
};
}
private void Button_Refresh_Click(object sender, RoutedEventArgs e)
{
Message.Text = "working...";
Button_Refresh.IsEnabled = false;
backgroundWorker.RunWorkerAsync();
}
}
}
答案 0 :(得分:3)
如果您希望在任务运行时更新UI(并保持响应),则需要使用单独的线程,例如使用BackgroundWorker
。
代码示例(未经测试):
BackgroundWorker bwButtonWorker;
public Window1() {
InitializeComponent();
bwButtonWorker = new BackgroundWorker();
bwButtonWorker.DoWork += (sender, args) => {
// do your lengthy stuff here -- this happens in a separate thread
Thread.Sleep(2000);
}
bwButtonWorker.RunWorkerCompleted += (sender, args) => {
// this happens in the UI thread, so you can modify your UI elements here
Message.Text = "Button is ready to click again.";
Button_Refresh.IsEnabled = true;
}
}
private void Button_Refresh_Click(object sender, RoutedEventArgs e)
{
Message.Text = "working...";
Button_Refresh.IsEnabled = false;
bwButtonWorker.RunWorkerAsync();
}
答案 1 :(得分:2)
另一种方法,值得: -
private void Button_Refresh_Click(object sender, RoutedEventArgs e)
{
Message.Text = "working...";
Button_Refresh.IsEnabled = false;
ThreadPool.QueueUserWorkItem(delegate(object state)
{
Thread.Sleep(2000);
Message.Dispatcher.Invoke((Action)delegate()
{
Message.Text = "Button is ready to click again.";
Button_Refresh.IsEnabled = true;
});
});
}
答案 2 :(得分:1)
您必须在单独的线程上运行您的任务。一个简单的方法是使用Button.Invoke方法。
答案 3 :(得分:0)
不要使用Control.Invoke() - 它的内部实现完全糟糕。 Invoke()导致一个线程等待另一个线程,因此可能会引入死锁。你应该总是使用非阻塞的BeginInvoke()。