WPF的UI更新方式

2021-06-05 06:10:21 字數 2735 閱讀 8806

那在 wpf 中,要如何更新 ui 的內容呢?

當然,要從乙個不正確的範例開始。

ex1bad.xaml

xmlns=""

xmlns:x=""

title="ex1bad"height="300"width="300">

ex1bad.xaml.cs

usingsystem.threading;

usingsystem.windows;

privatevoid btnstart_click(objectsender, routedeventargs e)

}}

這裡以 thread.sleep(3000)讓 ui thread 睡個3秒鐘,來模擬長時間的工作。

ex2winformdoevents.xaml

usingsystem.threading;

usingsystem.windows;

usingswf = system.windows.forms;

privatevoid btnstart_click(objectsender, routedeventargs e)

}}

哦?wpf 沒有 doevents 可以使用,只能呼叫老前輩windows form 的 api 嗎?也不是。在 dispacherframe 文章中就有sample.

ex3wpfdoevents.xaml.cs

usingsystem;

usingsystem.security.permissions;

usingsystem.threading;

usingsystem.windows;

usingsystem.windows.threading;

privatevoid btnstart_click(objectsender, routedeventargs e)

[securitypermissionattribute(securityaction.demand, flags = securitypermissionflag.unmanagedcode)]

publicvoid doevents()

publicobject exitframe(objectf)

publicstatic void doevents2()

;dispatcher.currentdispatcher.invoke(dispatcherpriority.input, action);

}}}

doevents() 與 doevents2() 的效果相同。

doevents 這麼好用,為什麼wpf還要發明 dispatcher,或 windows form 的 begininvoke 這些 api  呢?

跑以下的程式碼看看吧。

privatevoid btnevil_click(objectsender, routedeventargs e)

messagebox.show("ok");

}

執行時,記得開啟任務管理器看看cpu 的負載,會持續飆高一斷時間。雖然 ui 沒有任何的更新,為何 cpu 會飆高呢?

doevent 的原理是execution loop,也就是以迴圈的方式來查詢是否有要更新的訊息(message)。一看到迴圈,各位看倌就知道是怎麼回事了吧。

範例3中的wpf 的 doevents 也是相同的道理。

有沒有較正常的方式來更新 ui 呢?看一下ex1bad.xaml.cs的設計方式吧。更新lblmessage後執行一段工作,這基本上是同步的寫作方式。在 ui thread 上執行工作,本來就會使得 ui 停頓,使用者感到不方變。

正確的方式,是使用backgroundworker來首席執行官時間的工作,並以非同步的方式更新在 ui tread 上的ui內容。

ex4backgroundworker.xaml.cs

usingsystem.componentmodel;

usingsystem.threading;

usingsystem.windows;

usingsystem.windows.controls;

privatevoid btnstart_click(objectsender, routedeventargs e)

privatevoid executelongtimework(label label, stringmessage)

;backgroundworker.runworkercompleted += (s, args) =>

));};

backgroundworker.runworkerasync();

}}}

backgroundworker 工作方式,是建立乙個新的 thread 來執行 dowork 的event handler,執行完畢後,再執行 runworkercompleted 的event handler。因此,我們需要的是在runworkercompleted 的event handler 中更新的 ui。

更新 ui 時,又使用 dispatcher 來更新 ui。基本上,dispatcher 是乙個 queue 的概念,凡是使用 dispatcher 來更新 ui,wpf 會照 dispatcherpriority 的優先順序來更新 ui。

雖然只是小小的ui 更新方式,也是有不少的學問呢!

UI更新方法

在講解更新ui方法前,我們先來了解一些概念 當應用啟動,系統會建立乙個 主線程 main thread 這個主線程負責向ui元件分發事件 包括繪製事件 ui的更新也必須在主線程中完成,讓主線程做處理,因此也可以說,主線程即ui執行緒。主線程主要的職責是 1 快速處理ui事件,2 快速處理broadc...

WPF非同步更新UI

因為你在乙個非ui執行緒裡開啟了乙個ui執行緒,所有需要用dispatcher.invokeasync,切換到ui執行緒 詳細的解釋 我們需要通過訪問window.dispatcher屬性,然後呼叫invoke方法 僅此而已 好吧,那麼到底什麼是dispatcher呢?從字面上來說,它是所謂的接線員...

WPF跨執行緒更新UI控制項

1.預設情況下,在windows應用程式中,net framework不允許在乙個執行緒中直接操作另乙個執行緒中的控制項。winform中實現跨執行緒操作控制項的兩種方法 1 關閉執行緒安全檢查 control.checkforillegalcrossthreadcalls false 2 使用控制...