Winform 里有 Application.DoEvents();可刷新!
WPF 里沒這個,盡管可用委托實現多線程,但是刷新還是不行!
后來找到了 類似App.DoEvents()的方法();
代碼:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
namespace wgscd
{
public partial class App : Application
{
private static DispatcherOperationCallback exitFrameCallback = new DispatcherOperationCallback(ExitFrame);
public static void DoEvents()
{
DispatcherFrame nestedFrame = new DispatcherFrame();
DispatcherOperation exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke (DispatcherPriority.Background, exitFrameCallback, nestedFrame);
Dispatcher.PushFrame(nestedFrame);
if (exitOperation.Status !=
DispatcherOperationStatus.Completed)
{
exitOperation.Abort();
}
}
private static Object ExitFrame (Object state)
{
DispatcherFrame frame = state as
DispatcherFrame;
frame.Continue = false;
return null;
}
}
}
------------------------------------------------------------------
這樣在需要調用刷新的地方就可:App.DoEvents();
-----------------例子--------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
namespace wgscd
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
myDothread = new DoThread(doJob);
t.Tick+=new EventHandler(t_Tick);
t.Interval = TimeSpan.FromMilliseconds( 100d);
t.Start();
}
int i = 0;
public delegate void DoThread();
DoThread myDothread;
DispatcherTimer t = new DispatcherTimer();//定義一個 定時器
void t_Tick(object sender ,EventArgs e){
this.Title = DateTime.Now .ToString();
// textBox1.Text = i.ToString();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = "11";
myDothread.BeginInvoke(null,null );
}
void doJob() {
i = 0;
//System.Windows.Threading.Dispatcher.Run();
DoThread dotd = delegate()
{
// Thread.Sleep(20000); //這樣就會讓 按鈕(button1)假死,WPF還是 無能為力嗎?
while (i < 33773)
{
textBox1.Text =i.ToString();
i++;
// textBox1.UpdateLayout();
App.DoEvents();//這里可刷新文本框!
}
};
this.Dispatcher.BeginInvoke(dotd,null);
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = "hello";
}
}
}
//--------------------------------------------------------------------------------------------------------
第1種用 Task類. 推薦用這個辦法
publicvoid工作_Task()
{
Dispatcher x=Dispatcher.CurrentDispatcher;//取得當前工作線程
//另開線程工作
Task<int>計數=newTask<int>(()=>{return計數方法(); });
計數.ContinueWith(工作完畢后方法);//工作完畢后執行的方法
計數.Start();//開始工作
}
publicvoid工作完畢后方法(Task<int>參數)
{
if(參數.IsCompleted)//正常工作完畢
{
var 結果=參數.Result;//取得結果
//處理結果.
//本方法非界面線程.如果需要在界面線程操作,需要轉移到界面線程
}
}
intc;
publicint計數方法()
{
returnc++;
}
第2種方法用線程
publicvoid工作_Thread()
{
Dispatcher x=Dispatcher.CurrentDispatcher;//取得當前工作線程
//另開線程工作
System.Threading.ThreadStart start=delegate()
{
//工作函數
Func<string>fu=newFunc<string>(()=>{return""; });//工作函數
var 工作結果=fu();//開始工作
//異步更新界面
x.BeginInvoke(newAction(()=>
{
//在界面線程操作 可以使用 工作結果
}), DispatcherPriority.Normal);
};
newSystem.Threading.Thread(start).Start();//啟動線程
}
第3種方法用 BackgroundWorker.
BackgroundWorker 后台線程;
publicvoid線程初始化()
{
后台線程=newBackgroundWorker();
后台線程.WorkerSupportsCancellation=true;//可以取消
后台線程.DoWork+=newDoWorkEventHandler(后台線程_DoWork);
后台線程.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(后台線程_RunWorkerCompleted);
}
publicvoid啟動后台線程()
{
后台線程.RunWorkerAsync();
}
void后台線程_RunWorkerCompleted(objectsender, RunWorkerCompletedEventArgs e)
{
//工作完畢的方法
}
void后台線程_DoWork(objectsender, DoWorkEventArgs e)
{
//工作方法
}