我想要在单击按钮时显示自定义WPF控件,并在处理完成时隐藏,我正在尝试此操作,但在处理完成之前控件不可见。
public delegate void UpdateTextCallback(string message);
private void UpdateText(string message)
{
if (message == "v")
crclLoading.Visibility = Visibility.Visible;
else
crclLoading.Visibility = Visibility.Hidden;
}
private void TestThread()
{
crclLoading.Dispatcher.Invoke(
new UpdateTextCallback(this.UpdateText),
new object[] {"v" }
);
}
private void TestThread2()
{
crclLoading.Dispatcher.Invoke(
new UpdateTextCallback(this.UpdateText),
new object[] { "s" }
);
}
并在butoon_click:
Thread show= new Thread(new ThreadStart(TestThread));
show.Start();
//long time conusming processing
Thread hide= new Thread(new ThreadStart(TestThread2));
hide.Start();
答案 0 :(得分:2)
您在后台线程上所做的就是调用Dispatcher.Invoke
,这会在UI线程上同步执行指定的委托。
此外,您在启动第一个线程后立即启动第二个线程,而您的代码根本没有多大意义。
您需要在后台线程上实际执行一些可能长时间运行的操作。
顺便说一下,在后台线程上执行某些操作的推荐方法是现在启动一个新的Task
。试试这个:
crclLoading.Visibility = Visibility.Visible;
Task.Factory.StartNew(()=>
{
//do something that might take a while here....
System.Threading.Thread.Sleep(5000);
}).ContinueWith(task =>
{
//and then set the Visibility to Hidden once the task has finished
crclLoading.Visibility = Visibility.Hidden;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
答案 1 :(得分:2)
在WPF中,只有创建DispatcherObject
的线程才能访问该对象。例如,从主UI线程分离出来的后台线程无法更新在UI线程上创建的Button
的内容。为了让后台线程访问Button的Content
属性,后台线程必须将工作委托给与UI线程关联的Dispatcher。这是通过使用Invoke
或BeginInvoke
来完成的。 Invoke
是同步的,BeginInvoke
是异步的。该操作将添加到指定Dispatcher
的{{1}}的事件队列中。
DispatcherPriority
是同步操作;因此,在回调函数返回之前,控件不会返回调用对象。
使用Invoke