李曉京,馬 進(jìn),胡文東,張利利,惠鐸鐸
(第四軍醫(yī)大學(xué) 航空航天醫(yī)學(xué)教育部重點(diǎn)實(shí)驗(yàn)室,陜西 西安 710032)
WPF技術(shù)在蒙塞爾色相仿真測(cè)試中的應(yīng)用
李曉京,馬 進(jìn),胡文東,張利利,惠鐸鐸
(第四軍醫(yī)大學(xué) 航空航天醫(yī)學(xué)教育部重點(diǎn)實(shí)驗(yàn)室,陜西 西安 710032)
蒙塞爾色相測(cè)試(Farnsworth-Munsell Hue Test)用于檢測(cè)色覺(jué)缺陷人員的色弱區(qū)域,該測(cè)試的計(jì)算機(jī)仿真應(yīng)用在一些方面存在不足。文中在對(duì)蒙塞爾測(cè)試需求分析的基礎(chǔ)上,提出了基于.Net WPF技術(shù)的色相子操作仿真軟件功能設(shè)計(jì)方案,重點(diǎn)闡述了色相子控件類、控件拖放行為類、基于屬性觸發(fā)器的層次效果、泛型容器排序算法以及由故事板控制的色相子移位動(dòng)畫(huà)設(shè)計(jì)思路。最終實(shí)現(xiàn)的色相子操作仿真界面具有分辨率自適應(yīng)、色相子操作仿真特效、色相子移位多重業(yè)務(wù)邏輯等特點(diǎn),能夠充分滿足目標(biāo)應(yīng)用需求。
WPF;Farnsworth-Munsell色相測(cè)試;自定義控件;行為類;屬性觸發(fā)器;泛型;故事板
WPF(Windows Presentation Foundation)是一個(gè)用于Windows的針對(duì).NET設(shè)計(jì)的圖形顯示系統(tǒng),基于WPF開(kāi)發(fā)的應(yīng)用程序界面底層都使用DirectX技術(shù),從而使得再普通不過(guò)的應(yīng)用程序也能使用諸如半透明、抗鋸齒等豐富的效果,并由DirectX將圖形渲染任務(wù)盡可能多地交給顯卡GPU處理,從而大大提高了硬件加速性能。其“界面UI設(shè)計(jì)”與“后臺(tái)編程”相分離的設(shè)計(jì)思想,使得界面元素外觀能夠以類似圖形編輯的方式輕松實(shí)現(xiàn),使得編程人員得以專注于代碼和業(yè)務(wù)邏輯分析,二相結(jié)合創(chuàng)造出優(yōu)秀用戶體驗(yàn)的交互設(shè)計(jì)。另外,WPF可以實(shí)現(xiàn)資源構(gòu)件化開(kāi)發(fā),資源的設(shè)計(jì)與開(kāi)發(fā)具有很高的可重用性[1-9]。
蒙塞爾色相測(cè)試(Farnsworth-Munsell Hue Test)用于檢測(cè)色覺(jué)缺陷人員的色弱區(qū)域[10]。目前可以找到一些Win32仿真測(cè)試軟件[11-13],在實(shí)用時(shí)發(fā)現(xiàn)存在一些不足:
(1)選中的色相子缺乏相對(duì)其他色相子的空間層次效果;
(2)拖拽釋放色相子對(duì)象后,色相子隊(duì)列的重排是一個(gè)跳變過(guò)程,色相子對(duì)象位移沒(méi)有過(guò)渡,易使受測(cè)者產(chǎn)生困惑和懷疑;
(3)軟件界面大小無(wú)法調(diào)節(jié),在高分辨率顯示器上不能全屏?xí)@得交互界面過(guò)小。
從測(cè)試實(shí)物外觀及相應(yīng)仿真軟件的不足之處可見(jiàn),該仿真應(yīng)用存在如下關(guān)鍵需求:
色相子仿真控件:由于實(shí)物色相子具有相同的外觀,僅色相不同且數(shù)量較多,因此合理的作法是將其設(shè)計(jì)為可重用控件,提供顏色設(shè)置屬性以便編程。
色相子拖拽跟隨及層次特效:采用鼠標(biāo)操作模擬手工挪動(dòng)色相子的位置變化,同時(shí)添加陰影效果,模擬控件的懸空狀態(tài)。
色相子釋放后的排序業(yè)務(wù)邏輯:在色相子拖拽釋放后,需要根據(jù)其新的位置信息來(lái)判斷它應(yīng)該歸置于什么標(biāo)準(zhǔn)位置,從而引起整個(gè)色相子隊(duì)列的重排。
色相子歸位動(dòng)畫(huà):用戶在釋放色相子控件后,如果參與排序業(yè)務(wù)的色相子控件都直接按照排序結(jié)果直接出現(xiàn)在其標(biāo)準(zhǔn)位置上,無(wú)疑是一種位置和色彩的突變,在視覺(jué)上會(huì)給用戶帶來(lái)不適以及對(duì)排序結(jié)果的懷疑與錯(cuò)愕。因此,在完成排序業(yè)務(wù)邏輯運(yùn)算后,讓色相子控件以過(guò)渡動(dòng)畫(huà)的形式運(yùn)動(dòng)到它們的標(biāo)準(zhǔn)位置上,一方面與現(xiàn)實(shí)情況更為接近,另一方面可以讓用戶直觀地觀察到排序動(dòng)態(tài)過(guò)程,從而增強(qiáng)其操作信心。
分辨率無(wú)關(guān)的自動(dòng)縮放效果:由于用戶顯示器尺寸和分辨率設(shè)置有種種可能,目標(biāo)應(yīng)用應(yīng)能隨著用戶控制交互界面的放大、縮小而自適應(yīng)地調(diào)整界面控件元素的大小,從而滿足不同用戶的喜好。
從前述可知,WPF技術(shù)可以全方位滿足目標(biāo)應(yīng)用需求,特別是在用戶界面的美觀優(yōu)化與交互人性化設(shè)計(jì)方面,具有顯著的優(yōu)勢(shì)。
在WPF豐富的繪圖模型以及聲明式用戶界面的支持下,與專業(yè)設(shè)計(jì)工具Expression Blend相配合,圖形自定義控件的開(kāi)發(fā)變得簡(jiǎn)單而直觀。在Expression Blend中導(dǎo)入豐富的圖形構(gòu)建更加漂亮的控件,與在Photoshop中進(jìn)行圖形處理同樣容易[14]。簡(jiǎn)便起見(jiàn),下面以一個(gè)簡(jiǎn)單明了的自定義控件加以演示和說(shuō)明。
自定義控件的可視化樹(shù)及外觀如圖1所示。
由可視化樹(shù)可見(jiàn),派生于UserControl的色相子控件由簡(jiǎn)單的四個(gè)元素構(gòu)成。其中,第一個(gè)path元素是一個(gè)無(wú)色圓形,將其填充畫(huà)刷命名為CColor;第二個(gè)path則仿真色相子的環(huán)狀邊框覆蓋在上方。這兩個(gè)path元素嵌套在Canvas面板中置于Viewbox元素中,通過(guò)將Viewbox元素的Stretch屬性設(shè)置為"Uniform"實(shí)現(xiàn)控件在應(yīng)用時(shí)的一致性縮放。
圖1 色相子控件可視化外觀
后臺(tái)代碼工作主要是為控件創(chuàng)建三個(gè)依賴項(xiàng)屬性:ToTop、ToLeft、IsPressed。前兩個(gè)屬性用于控件實(shí)例的拖放歸位動(dòng)畫(huà),后者用于控件實(shí)例的拖放狀態(tài)層次效果屬性觸發(fā)器。將前述CColor畫(huà)刷的Color屬性封裝為控件的CenterColor屬性公開(kāi),通過(guò)該屬性可直接設(shè)定色相子控件實(shí)例的中心顏色。
主要代碼如下:
public partial class UserControl :UserControl
{
public Color CenterColor //該屬性用于設(shè)置色相子的顏色
{
set{CColor.Color=value;}
get{return (Color)CColor.Color;}
}
// ToLeftProperty依賴項(xiàng)屬性用于控件拖放歸位動(dòng)畫(huà)
public static readonly DependencyProperty ToLeftProperty=
DependencyProperty.Register("ToLeft",
typeof(double),
typeof(UserControl1),
new FrameworkPropertyMetadata(0.0, null));
public double ToLeft
{
set{SetValue(ToLeftProperty, value);}
get{return (double)GetValue(ToLeftProperty);}
}
// ToTopProperty依賴項(xiàng)屬性與ToLeftProperty類似,定義從略
//IsPressedProperty依賴項(xiàng)屬性用于觸發(fā)控件拖放層次效果,bool型,定義從略
……
public UserControl1()
{
InitializeComponent();
}
}
需要強(qiáng)調(diào)的是,依賴項(xiàng)屬性的性質(zhì)決定了它支持動(dòng)態(tài)綁定,因此尤其適用于動(dòng)畫(huà)、界面元素動(dòng)態(tài)更新等需求,從而極大地簡(jiǎn)化了編程復(fù)雜度,但相應(yīng)地也會(huì)為其強(qiáng)大動(dòng)態(tài)功能付出系統(tǒng)資源代價(jià)。因此,在普通屬性和依賴性屬性的選擇方面要因需制宜。色相子控件中,CenterColor屬性就被聲明為普通屬性,這是由于色相子的中心顏色在程序生命周期中不會(huì)有動(dòng)態(tài)的變化,因此普通屬性就可以滿足需要。此外,并未為CenterColor屬性創(chuàng)建相應(yīng)的私有數(shù)據(jù),而是通過(guò)訪問(wèn)函數(shù)直接對(duì)其他元素屬性進(jìn)行操作,這種方式巧妙地達(dá)到了數(shù)據(jù)封裝和降低系統(tǒng)資源占用的目的,是.Net程序設(shè)計(jì)中一種非常實(shí)用的技巧。
仿真色相子界面用戶交互流程見(jiàn)圖2。
圖2 仿真色相子控件用戶交互流程
可見(jiàn),由色相子控件事件驅(qū)動(dòng)的拖放行為類、層次特效、控件排序業(yè)務(wù)邏輯、色相子歸位動(dòng)畫(huà)等功能模塊相互作用,構(gòu)成了色相子仿真界面的人機(jī)交互邏輯。
3.1 色相子拖放行為類
WPF行為特征旨在代碼重用,封裝好的行為類可以為用戶界面上具有相同操作響應(yīng)的元素提供統(tǒng)一的操作支持。設(shè)計(jì)拖放行為類可以滿足色相子的拖放操作仿真,并降低代碼工作量。
DragInCanvasBehavior由泛型類Behavior
一個(gè)完整色相子的拖放行為仿真由鼠標(biāo)左鍵按下、鼠標(biāo)移動(dòng)、鼠標(biāo)左鍵松開(kāi)這一系列鼠標(biāo)事件構(gòu)成,因此,目標(biāo)行為類定義了對(duì)這三個(gè)事件的響應(yīng)函數(shù)。此外,由于拖放操作完成后有后續(xù)的排序歸位動(dòng)畫(huà),且在動(dòng)畫(huà)執(zhí)行期間不允許執(zhí)行下一次操作任務(wù),因此,還需要為行為類添加兩個(gè)委托事件,PreDrag用于檢測(cè)是否處于動(dòng)畫(huà)狀態(tài),DragEnd用于通知主程序拖放完成可以開(kāi)始排序歸位動(dòng)畫(huà)。該類的主要代碼如下:
public class DragInCanvasBehavior:Behavior
{
private Canvas canvas; //用于保存控件的父容器面板
private bool isDragging=false;//用于鼠標(biāo)移動(dòng)時(shí)判斷是否處于拖放狀態(tài)
private Point mouseOffset;//鼠標(biāo)位置偏移量
//下兩行定義拖放結(jié)束事件委托
public delegate void DragEndHandler(Object sender);
public event DragEndHandler DragEnd;
//下兩行定義拖放預(yù)檢事件委托
public delegate bool PreDragHandler(Object sender);
public event PreDragHandler PreDrag;
protected override void OnAttached()
{//重載附著函數(shù),將相關(guān)響應(yīng)函數(shù)添加到控件委托
base.OnAttached();
//MouseLeftButtonDown委托關(guān)聯(lián),MouseMove、MouseLeftButtonUp相類從略
this.AssociatedObject.MouseLeftButtonDown+=AssociatedObject_MouseLeftButtonDown;
……
}
protected override void OnDetaching()
{ //重載解除附著函數(shù),從事件委托列表中刪除相關(guān)函數(shù)
base.OnDetaching();
//MouseLeftButtonDown解除委托關(guān)聯(lián),MouseMove、Mouse-LeftButtonUp相類從略
this.AssociatedObject.MouseLeftButtonDown-=AssociatedObject_MouseLeftButtonDown;
……
}
private void AssociatedObject_MouseLeftButtonDown(Object sender,MouseButtonEventArgs e) //控件鼠標(biāo)左擊事件響應(yīng)函數(shù)
{
if(null!=PreDrag) if (!PreDrag(AssociatedObject)) return; //若不可進(jìn)入拖放狀態(tài),返回
if(canvas==null)
canvas=(Canvas)VisualTreeHelper.GetParent(this.AssociatedObject); //獲取控件父面板
isDragging=true; //進(jìn)入拖放狀態(tài)標(biāo)志置位
//獲取點(diǎn)擊點(diǎn)相對(duì)控件的坐標(biāo)(元素左上為0,0)
mouseOffset=e.GetPosition(AssociatedObject);
//捕獲鼠標(biāo),持續(xù)接收mousemove事件,即使其離開(kāi)控件
AssociatedObject.CaptureMouse();
}
private void AssociatedObject_MouseMove(Object sender, MouseEventArgs e)
{//控件鼠標(biāo)移動(dòng)事件響應(yīng)函數(shù)
if(isDragging)//拖放狀態(tài)下,控件進(jìn)入鼠標(biāo)跟隨效果
{//計(jì)算控件的新位置并設(shè)置其位置附加屬性
Point point=e.GetPosition(canvas);
Point pTemp=new Point(point.X-mouseOffset.X,point.Y-mouseOffset.Y);
……
//控件移動(dòng)(應(yīng)限制控件位置不得超出父面板邊界,代碼從略)
AssociatedObject.SetValue(Canvas.TopProperty,pTemp.Y);
AssociatedObject.SetValue(Canvas.LeftProperty,pTemp.X);
}
}
private void AssociatedObject_MouseLeftButtonUp(Object sender,MouseButtonEventArgs e)
{//控件左鍵松開(kāi)響應(yīng)函數(shù)
if(isDragging)
{
AssociatedObject.ReleaseMouseCapture();//解除捕獲鼠標(biāo)
isDragging=false; //拖放狀態(tài)標(biāo)志清除
//調(diào)用拖放結(jié)束委托函數(shù),通知主線程執(zhí)行排序運(yùn)算和歸位動(dòng)畫(huà)
if(null!=DragEnd) DragEnd(AssociatedObject);
}
}
}
3.2 色相子控件應(yīng)用與層次特效
在Xmal聲明文件中,采用常規(guī)的程序集引用和控件聲明即可實(shí)現(xiàn)色相子控件的應(yīng)用,以兩個(gè)Canvas面板各含5個(gè)色相子控件為例,界面元素及可視化樹(shù)見(jiàn)圖3。
注:UserControl2是用于表示色相子標(biāo)準(zhǔn)位置的圖形控件,可忽略。
色相子及行為聲明示例代碼如下所示:
CenterColor="#FF873787" Height="50" Width="50" Panel.ZIndex="1">
注意在以上聲明中,已將后臺(tái)定義的PreDrag、DragFinished函數(shù)關(guān)聯(lián)到附著行為類相應(yīng)委托事件上。
拖放色相子時(shí)的層次特效首先是提升色相子在面板中的疊放層次,使受拖放控件呈現(xiàn)于其他控件之上,這將由后臺(tái)代碼來(lái)完成。其次,當(dāng)進(jìn)入拖動(dòng)狀態(tài)時(shí),可創(chuàng)建陰影效果,形成該色相子懸浮于空中的視覺(jué)效果。特效在Xaml文件的窗體資源中聲明,由前述色相子控件的自定義的IsPressed屬性觸發(fā),Xaml聲明如下:
Color="#FF313030" Opacity="0.5" BlurRadius="5"/> 還可以通過(guò)故事板為陰影特效創(chuàng)建漸入漸出動(dòng)畫(huà)以實(shí)現(xiàn)更為逼真的操作效果,這里就不作介紹了。 3.3 色相子排序業(yè)務(wù)邏輯與歸位動(dòng)畫(huà) 色相子拖放與歸位動(dòng)畫(huà)的中間環(huán)節(jié)是根據(jù)其被釋放時(shí)的位置計(jì)算整個(gè)色相子隊(duì)列成員的新位置。為了充分滿足用戶需求,設(shè)計(jì)插入和交換兩種業(yè)務(wù)邏輯供用戶選擇,插入/交換的目標(biāo)位置可就近或空位側(cè)優(yōu)先,如圖4所示。 圖4 色相子排序業(yè)務(wù)邏輯示例 這里以相對(duì)復(fù)雜的插入邏輯加以說(shuō)明。 初始化時(shí),將所有色相子控件實(shí)例保存在列表泛型容器中,在拖放行為結(jié)束時(shí),根據(jù)被拖放的色相子位置,調(diào)整列表中的控件排序,按排好的順序?qū)?biāo)準(zhǔn)位置賦給各色相子的ToTop、ToLeft依賴項(xiàng)屬性,并進(jìn)入下一步的歸位動(dòng)畫(huà)。 歸位動(dòng)畫(huà)由動(dòng)態(tài)創(chuàng)建的Storyboard實(shí)例控制,動(dòng)畫(huà)開(kāi)始時(shí)將指示動(dòng)畫(huà)狀態(tài)標(biāo)志量置位,提交給拖放行為類的PreDrag委托函數(shù)將檢測(cè)該標(biāo)志以確定能否進(jìn)入后續(xù)的拖放操作狀態(tài)。 核心代碼如下: public partial class Window2:Window { //多組色相子放在不同的Canvas面板中,對(duì)每個(gè)面板同時(shí)只允許執(zhí)行一個(gè)歸位動(dòng)畫(huà),因此定義面板與故事板的配對(duì)查詢字典 private Dictionary //每個(gè)面板中所包含的色相子控件組保存在不同的泛型列表容器中,因此定義面板與列表容器的配對(duì)查詢字典 private Dictionary //示例用兩組面板和色相子控件組,因此定義兩組保存色相子控件組的列表容器 List List //由于色相子Top都一樣,只須保存各控件Left屬性值;兩組控件共享一組Left坐標(biāo)數(shù)組 List public bool bIsAnimming=false; //是否處于動(dòng)畫(huà)狀態(tài)標(biāo)志位 public Window2() {//構(gòu)造函數(shù),完成初始化工作 int i; InitializeComponent(); //將Xaml文件聲明的兩個(gè)面板與列表容器配對(duì)加入字典 dicCanPairedUCList.Add(can1,lstCtr1); dicCanPairedUCList.Add(can2,lstCtr2); for(i=0;i< can1.Children.Count;i++) {//逐一將面板1中色相子實(shí)例入列,并保存標(biāo)準(zhǔn)位置數(shù)據(jù) if (can1.Children[i].GetType()!=typeof(UserControl1)) continue; lstCtr.Add((UserControl1)can1.Children[i]); ((UserControl1)can1.Children[i]).ToTop=//ToTop屬性全程不變 (double)((UserControl1)can1.Children[i]).GetValue(Canvas.TopProperty); lstXPos.Add((double)((UserControl1)can1.Children[i]).GetValue(Canvas.LeftProperty)); } //逐一將面板2中色相子入列,代碼從略 for(i=0;i } // DragFinished在Xaml控件聲明中關(guān)聯(lián)至控件拖放行為的DragEnd事件 public void DragFinished(Object obj) { int i,j=0; double dtemp,mindiff=10000; //三行代碼根據(jù)回調(diào)參數(shù)確定色相子控件、父面板及其配對(duì)列表容器 UserControl1 ctr=(UserControl1)obj; Canvas can=(Canvas)VisualTreeHelper.GetParent(ctr); List if(bIsNearIns){ //若是就近插入邏輯 for(i=0;i {/*dtemp用于保存受拖動(dòng)控件與組內(nèi)各控件的距離; 距離最小的控件序號(hào)將保存在變量j中,代碼從略*/ dtemp=Math.Abs(lstXPos.ElementAt(i)-(double)(ctr.GetValue(Canvas.LeftProperty))); …… } //將被拖放的控件插入到新的位置 lstCtrTemp.Remove(ctr); if(j==lstCtrTemp.Count)lstCtrTemp.Add(ctr); else lstCtrTemp.Insert(j,ctr); } else{//空位側(cè)優(yōu)先插入邏輯直接采用Lambda表達(dá)式完成冒泡排序 lstCtrTemp.Sort((ctr1,ctr2)=>{ return(double)ctr1.GetValue(Canvas.LeftProperty) < (double)ctr2.GetValue(Canvas.LeftProperty) ? -1:1;}); } //交換業(yè)務(wù)邏輯從略 …… //創(chuàng)建故事板實(shí)例sb并行管理一組色相子的歸位動(dòng)畫(huà) Storyboard sb=new Storyboard(); for(i=0;i { //將標(biāo)準(zhǔn)X坐標(biāo)賦給各色相子控件的ToLeft lstCtrTemp.ElementAt(i).ToLeft=lstXPos.ElementAt(i); //橫坐標(biāo)歸位動(dòng)畫(huà) DoubleAnimationctrAL=newDoubleAnimation(); ctrAL.To=lstCtrTemp.ElementAt(i).ToLeft; ctrAL.Duration=TimeSpan.FromSeconds(0.1); Storyboard.SetTarget(ctrAL,lstCtrTemp.ElementAt(i)); Storyboard.SetTargetProperty(ctrAL,newPropertyPath("(Canvas.Left)")); sb.Children.Add(ctrAL); //縱坐標(biāo)歸位動(dòng)畫(huà)與橫坐標(biāo)相類,代碼從略 …… } //動(dòng)畫(huà)時(shí)長(zhǎng)設(shè)置為0.1秒,以免拖延操作時(shí)間 sb.Duration=TimeSpan.FromSeconds(0.1); //動(dòng)畫(huà)結(jié)束清理工作函數(shù)提交給故事板結(jié)束事件委托 sb.Completed+=storyboard_Completed; sb.Begin(); storyboards.Add(can,sb);//將面板與動(dòng)畫(huà)配對(duì)加入字典 } //動(dòng)畫(huà)結(jié)束時(shí)將被執(zhí)行的清理函數(shù) privatevoidstoryboard_Completed(objectsender,EventArgse) { //由結(jié)束的故事板時(shí)間線對(duì)象查找受控色相子的父面板及其配對(duì)列表容器、配對(duì)故事板實(shí)例 ClockGroupclockGroup=(ClockGroup)sender; UserControl1ctrTemp=(UserControl1)Storyboard.GetTarget( (AnimationTimeline)clockGroup.Children[0].Timeline); Canvascan=(Canvas)VisualTreeHelper.GetParent(ctrTemp); List Storyboardstoryboard=storyboards[can]; //停止、清除動(dòng)畫(huà),并將面板、動(dòng)畫(huà)配對(duì)從字典中刪除 storyboard.Stop(); storyboard.Children.Clear(); storyboards.Remove(can); foreach(UserControl1ctrinlstctr) { //逐一將同組各色相子的目標(biāo)位置賦予自身的實(shí)際位置屬性 ctr.SetValue(Canvas.LeftProperty,ctr.ToLeft); ctr.SetValue(Canvas.TopProperty,ctr.ToTop); ctr.IsPressed=false; //清除控件拖放狀態(tài)標(biāo)志,去除層次效果 Canvas.SetZIndex(ctr,1); //恢復(fù)控件初始層次 } } //PreDrag函數(shù)在Xmal聲明中關(guān)聯(lián)到控件拖放行為的PreDrag事件 privateboolPreDrag(objectsender) { UserControl1ctr=(UserControl1)sender; //檢查色相子控件的父面板是否處于動(dòng)畫(huà)狀態(tài) boolbTemp=storyboards.ContainsKey(((Canvas)ctr.Parent)) ?false:true; if(bTemp) {//不在動(dòng)畫(huà)狀態(tài)即將進(jìn)入拖放操作 Canvas.SetZIndex(ctr, 2);//提升控件疊放層次 ctr.IsPressed=true;//設(shè)置拖放標(biāo)志,觸發(fā)層次特效 } returnbTemp; } } 為色相子控件定義的ToLeft、ToTop依賴項(xiàng)屬性作用在故事板中得到體現(xiàn)。如果不這樣設(shè)計(jì),就需要在主窗體中為全部色相子定義相應(yīng)的依賴項(xiàng)屬性數(shù)組,那樣代碼邏輯顯然要混亂很多,并且當(dāng)界面色相子控件數(shù)量發(fā)生變化時(shí),也會(huì)帶來(lái)代碼維護(hù)上的不便。 本例中用到了Dictionary 3.4 與分辨率無(wú)關(guān)的自適應(yīng)界面設(shè)計(jì) 對(duì)于Win32應(yīng)用來(lái)說(shuō),控件隨著界面的大小而自動(dòng)縮放是一項(xiàng)繁瑣的任務(wù)。但由于WPF強(qiáng)大的布局設(shè)計(jì)與圖形化界面功能,這幾乎不算一個(gè)問(wèn)題。如圖3中的可視化樹(shù)所示,將面板包含在Viewbox中,并根據(jù)需要設(shè)置Viewbox的Stretch、StretchDirection屬性,就可以實(shí)現(xiàn)控件隨用戶界面大小而自適應(yīng)地動(dòng)態(tài)調(diào)整自身大小,滿足用戶的視覺(jué)需求。如圖5所示,對(duì)比標(biāo)題欄大小可見(jiàn)兩個(gè)不同大小窗口中,控件完全隨著窗體的拉伸自適應(yīng)縮放并調(diào)整布局繪制,不需要任何后臺(tái)代碼。 圖5 仿真色相子界面自適應(yīng)縮放及布局 這種與界面大小無(wú)關(guān)的控件自適應(yīng)縮放與自動(dòng)布局充分體現(xiàn)了WPF的強(qiáng)大,其將編程人員從繁瑣的界面布局邏輯中完全解放出來(lái),從而可以更加專注于核心業(yè)務(wù)代碼設(shè)計(jì),對(duì)于程序開(kāi)發(fā)效率和用戶體驗(yàn)的提升具有劃時(shí)代的意義。 根據(jù)Farnsworth-Munsell色相測(cè)試系統(tǒng)實(shí)物使用特點(diǎn)及原有軟件的不足之處,文中提出了基于WPF技術(shù)的色相子仿真交互界面設(shè)計(jì)方案。該方案充分利用到.Net的圖形界面優(yōu)勢(shì),綜合運(yùn)用依賴項(xiàng)屬性、觸發(fā)器、故事板、泛型等.Net和WPF的優(yōu)勢(shì)特性,具有界面外觀可拓展性強(qiáng)、更接近實(shí)際物理特性的層次效果和仿真排序過(guò)渡動(dòng)畫(huà)、與分辨率無(wú)關(guān)的界面自適應(yīng)縮放與布局調(diào)整等特點(diǎn),并對(duì)涉及的關(guān)鍵技術(shù)進(jìn)行了詳細(xì)介紹。在Win32應(yīng)用逐漸落伍,個(gè)性化、富媒體化跨平臺(tái)應(yīng)用日益崛起的大背景下,文中介紹的.Net框架下的WPF相關(guān)技術(shù),對(duì)于圖形化界面與人機(jī)交互類的應(yīng)用開(kāi)發(fā)都有一定的借鑒意義。文中示例在Windows XP系統(tǒng)Visual Studio 2010 C#開(kāi)發(fā)環(huán)境下編譯,Win XP、Win 8操作系統(tǒng)測(cè)試通過(guò)。 [1] Troelsen A.C#與.Net 4高級(jí)程序設(shè)計(jì)[M].朱 曄,肖 逵,姚琪琳,等,譯.第5版.北京:人民郵電出版社,2011. [2] MacDonald M.WPF編程寶典—C#2010版[M].王德才,譯.北京:清華大學(xué)出版社,2011. [3] Petzold C.Windows Presentation Foundation程序設(shè)計(jì)指南[M].蔡學(xué)鏞,譯.北京:電子工業(yè)出版社,2008. [4] 王 鵬,崔 靜.新一代界面技術(shù)WPF的架構(gòu)及應(yīng)用[J].成都紡織高等??茖W(xué)校學(xué)報(bào),2011,28(1):18-20. [5] 張京明,曹國(guó)忠,張承業(yè),等.創(chuàng)新方法與交互設(shè)計(jì)結(jié)合的探討[J].價(jià)值工程,2012,31(10):10-11. [6] 李 穎.基于WPF的課堂教學(xué)管理系統(tǒng)研究與設(shè)計(jì)[J].中國(guó)教育技術(shù)裝備,2011(24):85-87. [7] 袁云云,周之昊.基于WPF的醫(yī)療輔助軟件設(shè)計(jì)與開(kāi)發(fā)[J].數(shù)字技術(shù)與應(yīng)用,2012(2):132-132. [8] 李成剛,馮 靜,凌 玲.基于WPF的交互式繪圖系統(tǒng)的開(kāi)發(fā)[J].微型機(jī)與應(yīng)用,2011,30(6):50-52. [9] Macdonald M.Pro WPF in C# 2008:Windows Presentation Foundation with .NET 3.5[M].New York:Apress,2008. [10] Farnsworth D.The Farnsworth-Munsell 100 hue and Dichotomous tests for color vision[J].Journal of the Optical Society of America B-optical Physics,1943,33:568-578. [11] Hidajat R R,Hidayat J R,McLay J L,et al.A fast system for reporting the Farnsworth-Munsell 100-hue colour vision test[J].Documenta Ophthalmologica,2004,109(2):109-114. [12] Ghose S,Parmar T,Dada T,et al.A new computer-based Farnsworth-Munsell 100-hue test for evaluation of color vision[J].International Ophthalmology,2014,34(4):747-751. [13] Melamud A,Simpson E,Traboulsi E I.Introducing a new computer-based test for the clinical evaluation of color discrimination[J].American Journal of Ophthalmology,2006,142(6):953-960. [14] 張洪定,孟冬梅.基于Expression Blend 4中文版 WPF和Silverlight項(xiàng)目設(shè)計(jì)基礎(chǔ)[M].北京:清華大學(xué)出版社,2011. Application of WPF in Farnsworth-Munsell Hue Simulation Testing System Development LI Xiao-jing,MA Jin,HU Wen-dong,ZHANG Li-li,HUI Duo-duo (Key Laboratory of Aerospace Medical of Ministry of Education,Fourth Military Medical University,Xi’an 710032,China) Farnsworth-Munsell Hue Test is applied to inspect the color weakness area of hypochromatopsia patients.But,for the computer simulation software of the test,there are some improvable aspects in the characteristics’ simulation.Based on the demand analysis of the test,a kind of software function and frame,utilizing .NET WPF,was developed for Hue-Token (HT) manipulating simulation.Primarily,the design of HT component,drag-drop behavior class,layer effect based on property trigger,sorting arithmetic of generic class and HT shifting animation under the control of storyboard were described in detail.Features of the final simulation interface such as resolution self-adaption,special effects of HT operation,multi-business logic of HT shift,could meet the need of demand of object application sufficiently. WPF (Windows Presentation Foundation);Farnsworth-Munsell Hue Simulation Testing;user control;behavior class;property trigger;generic type;storyboard 2015-04-08 2015-07-13 時(shí)間:2016-01-04 國(guó)家自然科學(xué)基金青年項(xiàng)目(81202178/H2602);全軍醫(yī)藥衛(wèi)生重大項(xiàng)目(AWS12J003) 李曉京(1975-),男,高級(jí)實(shí)驗(yàn)師,碩士,研究方向?yàn)橛?jì)算機(jī)應(yīng)用、生物醫(yī)學(xué)工程;馬 進(jìn),副研究員,博士,研究方向?yàn)樾睦韺W(xué);胡文東,研究員,碩士,研究方向?yàn)樾睦韺W(xué)、醫(yī)學(xué)工程。 http://www.cnki.net/kcms/detail/61.1450.TP.20160104.1510.060.html TP311 A 1673-629X(2016)02-0154-07 10.3969/j.issn.1673-629X.2016.02.0354 結(jié)束語(yǔ)