APP下载

WPF技术在蒙塞尔色相仿真测试中的应用

2016-02-23李晓京胡文东张利利惠铎铎

计算机技术与发展 2016年2期
关键词:色相控件鼠标

李晓京,马 进,胡文东,张利利,惠铎铎

(第四军医大学 航空航天医学教育部重点实验室,陕西 西安 710032)

WPF技术在蒙塞尔色相仿真测试中的应用

李晓京,马 进,胡文东,张利利,惠铎铎

(第四军医大学 航空航天医学教育部重点实验室,陕西 西安 710032)

蒙塞尔色相测试(Farnsworth-Munsell Hue Test)用于检测色觉缺陷人员的色弱区域,该测试的计算机仿真应用在一些方面存在不足。文中在对蒙塞尔测试需求分析的基础上,提出了基于.Net WPF技术的色相子操作仿真软件功能设计方案,重点阐述了色相子控件类、控件拖放行为类、基于属性触发器的层次效果、泛型容器排序算法以及由故事板控制的色相子移位动画设计思路。最终实现的色相子操作仿真界面具有分辨率自适应、色相子操作仿真特效、色相子移位多重业务逻辑等特点,能够充分满足目标应用需求。

WPF;Farnsworth-Munsell色相测试;自定义控件;行为类;属性触发器;泛型;故事板

0 引 言

WPF(Windows Presentation Foundation)是一个用于Windows的针对.NET设计的图形显示系统,基于WPF开发的应用程序界面底层都使用DirectX技术,从而使得再普通不过的应用程序也能使用诸如半透明、抗锯齿等丰富的效果,并由DirectX将图形渲染任务尽可能多地交给显卡GPU处理,从而大大提高了硬件加速性能。其“界面UI设计”与“后台编程”相分离的设计思想,使得界面元素外观能够以类似图形编辑的方式轻松实现,使得编程人员得以专注于代码和业务逻辑分析,二相结合创造出优秀用户体验的交互设计。另外,WPF可以实现资源构件化开发,资源的设计与开发具有很高的可重用性[1-9]。

蒙塞尔色相测试(Farnsworth-Munsell Hue Test)用于检测色觉缺陷人员的色弱区域[10]。目前可以找到一些Win32仿真测试软件[11-13],在实用时发现存在一些不足:

(1)选中的色相子缺乏相对其他色相子的空间层次效果;

(2)拖拽释放色相子对象后,色相子队列的重排是一个跳变过程,色相子对象位移没有过渡,易使受测者产生困惑和怀疑;

(3)软件界面大小无法调节,在高分辨率显示器上不能全屏会显得交互界面过小。

1 蒙塞尔色相子仿真软件需求分析

从测试实物外观及相应仿真软件的不足之处可见,该仿真应用存在如下关键需求:

色相子仿真控件:由于实物色相子具有相同的外观,仅色相不同且数量较多,因此合理的作法是将其设计为可重用控件,提供颜色设置属性以便编程。

色相子拖拽跟随及层次特效:采用鼠标操作模拟手工挪动色相子的位置变化,同时添加阴影效果,模拟控件的悬空状态。

色相子释放后的排序业务逻辑:在色相子拖拽释放后,需要根据其新的位置信息来判断它应该归置于什么标准位置,从而引起整个色相子队列的重排。

色相子归位动画:用户在释放色相子控件后,如果参与排序业务的色相子控件都直接按照排序结果直接出现在其标准位置上,无疑是一种位置和色彩的突变,在视觉上会给用户带来不适以及对排序结果的怀疑与错愕。因此,在完成排序业务逻辑运算后,让色相子控件以过渡动画的形式运动到它们的标准位置上,一方面与现实情况更为接近,另一方面可以让用户直观地观察到排序动态过程,从而增强其操作信心。

分辨率无关的自动缩放效果:由于用户显示器尺寸和分辨率设置有种种可能,目标应用应能随着用户控制交互界面的放大、缩小而自适应地调整界面控件元素的大小,从而满足不同用户的喜好。

从前述可知,WPF技术可以全方位满足目标应用需求,特别是在用户界面的美观优化与交互人性化设计方面,具有显著的优势。

2 色相子控件设计

在WPF丰富的绘图模型以及声明式用户界面的支持下,与专业设计工具Expression Blend相配合,图形自定义控件的开发变得简单而直观。在Expression Blend中导入丰富的图形构建更加漂亮的控件,与在Photoshop中进行图形处理同样容易[14]。简便起见,下面以一个简单明了的自定义控件加以演示和说明。

自定义控件的可视化树及外观如图1所示。

由可视化树可见,派生于UserControl的色相子控件由简单的四个元素构成。其中,第一个path元素是一个无色圆形,将其填充画刷命名为CColor;第二个path则仿真色相子的环状边框覆盖在上方。这两个path元素嵌套在Canvas面板中置于Viewbox元素中,通过将Viewbox元素的Stretch属性设置为"Uniform"实现控件在应用时的一致性缩放。

图1 色相子控件可视化外观

后台代码工作主要是为控件创建三个依赖项属性:ToTop、ToLeft、IsPressed。前两个属性用于控件实例的拖放归位动画,后者用于控件实例的拖放状态层次效果属性触发器。将前述CColor画刷的Color属性封装为控件的CenterColor属性公开,通过该属性可直接设定色相子控件实例的中心颜色。

主要代码如下:

public partial class UserControl :UserControl

{

public Color CenterColor //该属性用于设置色相子的颜色

{

set{CColor.Color=value;}

get{return (Color)CColor.Color;}

}

// ToLeftProperty依赖项属性用于控件拖放归位动画

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依赖项属性与ToLeftProperty类似,定义从略

//IsPressedProperty依赖项属性用于触发控件拖放层次效果,bool型,定义从略

……

public UserControl1()

{

InitializeComponent();

}

}

需要强调的是,依赖项属性的性质决定了它支持动态绑定,因此尤其适用于动画、界面元素动态更新等需求,从而极大地简化了编程复杂度,但相应地也会为其强大动态功能付出系统资源代价。因此,在普通属性和依赖性属性的选择方面要因需制宜。色相子控件中,CenterColor属性就被声明为普通属性,这是由于色相子的中心颜色在程序生命周期中不会有动态的变化,因此普通属性就可以满足需要。此外,并未为CenterColor属性创建相应的私有数据,而是通过访问函数直接对其他元素属性进行操作,这种方式巧妙地达到了数据封装和降低系统资源占用的目的,是.Net程序设计中一种非常实用的技巧。

3 色相子交互界面设计

仿真色相子界面用户交互流程见图2。

图2 仿真色相子控件用户交互流程

可见,由色相子控件事件驱动的拖放行为类、层次特效、控件排序业务逻辑、色相子归位动画等功能模块相互作用,构成了色相子仿真界面的人机交互逻辑。

3.1 色相子拖放行为类

WPF行为特征旨在代码重用,封装好的行为类可以为用户界面上具有相同操作响应的元素提供统一的操作支持。设计拖放行为类可以满足色相子的拖放操作仿真,并降低代码工作量。

DragInCanvasBehavior由泛型类Behavior派生,其中定义按键、松键等事件响应函数。重载基类的OnAttached(为元素声明添加行为特征时调用,通常在前台Xaml文件声明中为控件启用行为,即附着)、OnDetaching函数(元素销毁时被调用,即解除附着),在这两个函数中为被附着元素的相应事件委托添加(或删除)相应的行为响应函数。

一个完整色相子的拖放行为仿真由鼠标左键按下、鼠标移动、鼠标左键松开这一系列鼠标事件构成,因此,目标行为类定义了对这三个事件的响应函数。此外,由于拖放操作完成后有后续的排序归位动画,且在动画执行期间不允许执行下一次操作任务,因此,还需要为行为类添加两个委托事件,PreDrag用于检测是否处于动画状态,DragEnd用于通知主程序拖放完成可以开始排序归位动画。该类的主要代码如下:

public class DragInCanvasBehavior:Behavior

{

private Canvas canvas; //用于保存控件的父容器面板

private bool isDragging=false;//用于鼠标移动时判断是否处于拖放状态

private Point mouseOffset;//鼠标位置偏移量

//下两行定义拖放结束事件委托

public delegate void DragEndHandler(Object sender);

public event DragEndHandler DragEnd;

//下两行定义拖放预检事件委托

public delegate bool PreDragHandler(Object sender);

public event PreDragHandler PreDrag;

protected override void OnAttached()

{//重载附着函数,将相关响应函数添加到控件委托

base.OnAttached();

//MouseLeftButtonDown委托关联,MouseMove、MouseLeftButtonUp相类从略

this.AssociatedObject.MouseLeftButtonDown+=AssociatedObject_MouseLeftButtonDown;

……

}

protected override void OnDetaching()

{ //重载解除附着函数,从事件委托列表中删除相关函数

base.OnDetaching();

//MouseLeftButtonDown解除委托关联,MouseMove、Mouse-LeftButtonUp相类从略

this.AssociatedObject.MouseLeftButtonDown-=AssociatedObject_MouseLeftButtonDown;

……

}

private void AssociatedObject_MouseLeftButtonDown(Object sender,MouseButtonEventArgs e) //控件鼠标左击事件响应函数

{

if(null!=PreDrag) if (!PreDrag(AssociatedObject)) return; //若不可进入拖放状态,返回

if(canvas==null)

canvas=(Canvas)VisualTreeHelper.GetParent(this.AssociatedObject); //获取控件父面板

isDragging=true; //进入拖放状态标志置位

//获取点击点相对控件的坐标(元素左上为0,0)

mouseOffset=e.GetPosition(AssociatedObject);

//捕获鼠标,持续接收mousemove事件,即使其离开控件

AssociatedObject.CaptureMouse();

}

private void AssociatedObject_MouseMove(Object sender, MouseEventArgs e)

{//控件鼠标移动事件响应函数

if(isDragging)//拖放状态下,控件进入鼠标跟随效果

{//计算控件的新位置并设置其位置附加属性

Point point=e.GetPosition(canvas);

Point pTemp=new Point(point.X-mouseOffset.X,point.Y-mouseOffset.Y);

……

//控件移动(应限制控件位置不得超出父面板边界,代码从略)

AssociatedObject.SetValue(Canvas.TopProperty,pTemp.Y);

AssociatedObject.SetValue(Canvas.LeftProperty,pTemp.X);

}

}

private void AssociatedObject_MouseLeftButtonUp(Object sender,MouseButtonEventArgs e)

{//控件左键松开响应函数

if(isDragging)

{

AssociatedObject.ReleaseMouseCapture();//解除捕获鼠标

isDragging=false; //拖放状态标志清除

//调用拖放结束委托函数,通知主线程执行排序运算和归位动画

if(null!=DragEnd) DragEnd(AssociatedObject);

}

}

}

3.2 色相子控件应用与层次特效

在Xmal声明文件中,采用常规的程序集引用和控件声明即可实现色相子控件的应用,以两个Canvas面板各含5个色相子控件为例,界面元素及可视化树见图3。

注:UserControl2是用于表示色相子标准位置的图形控件,可忽略。

色相子及行为声明示例代码如下所示:

CenterColor="#FF873787" Height="50" Width="50" Panel.ZIndex="1">

注意在以上声明中,已将后台定义的PreDrag、DragFinished函数关联到附着行为类相应委托事件上。

拖放色相子时的层次特效首先是提升色相子在面板中的叠放层次,使受拖放控件呈现于其他控件之上,这将由后台代码来完成。其次,当进入拖动状态时,可创建阴影效果,形成该色相子悬浮于空中的视觉效果。特效在Xaml文件的窗体资源中声明,由前述色相子控件的自定义的IsPressed属性触发,Xaml声明如下:

还可以通过故事板为阴影特效创建渐入渐出动画以实现更为逼真的操作效果,这里就不作介绍了。

3.3 色相子排序业务逻辑与归位动画

色相子拖放与归位动画的中间环节是根据其被释放时的位置计算整个色相子队列成员的新位置。为了充分满足用户需求,设计插入和交换两种业务逻辑供用户选择,插入/交换的目标位置可就近或空位侧优先,如图4所示。

图4 色相子排序业务逻辑示例

这里以相对复杂的插入逻辑加以说明。

初始化时,将所有色相子控件实例保存在列表泛型容器中,在拖放行为结束时,根据被拖放的色相子位置,调整列表中的控件排序,按排好的顺序将标准位置赋给各色相子的ToTop、ToLeft依赖项属性,并进入下一步的归位动画。

归位动画由动态创建的Storyboard实例控制,动画开始时将指示动画状态标志量置位,提交给拖放行为类的PreDrag委托函数将检测该标志以确定能否进入后续的拖放操作状态。

核心代码如下:

public partial class Window2:Window

{

//多组色相子放在不同的Canvas面板中,对每个面板同时只允许执行一个归位动画,因此定义面板与故事板的配对查询字典

private Dictionary storyboards=new Dictionary();

//每个面板中所包含的色相子控件组保存在不同的泛型列表容器中,因此定义面板与列表容器的配对查询字典

private Dictionary> dicCanPairedUCList=new Dictionary>();

//示例用两组面板和色相子控件组,因此定义两组保存色相子控件组的列表容器

List lstCtr=new List();

List lstCtr2=new List();

//由于色相子Top都一样,只须保存各控件Left属性值;两组控件共享一组Left坐标数组

List lstXPos=new List();

public bool bIsAnimming=false; //是否处于动画状态标志位

public Window2()

{//构造函数,完成初始化工作

int i;

InitializeComponent();

//将Xaml文件声明的两个面板与列表容器配对加入字典

dicCanPairedUCList.Add(can1,lstCtr1);

dicCanPairedUCList.Add(can2,lstCtr2);

for(i=0;i< can1.Children.Count;i++)

{//逐一将面板1中色相子实例入列,并保存标准位置数据

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控件声明中关联至控件拖放行为的DragEnd事件

public void DragFinished(Object obj)

{

int i,j=0;

double dtemp,mindiff=10000;

//三行代码根据回调参数确定色相子控件、父面板及其配对列表容器

UserControl1 ctr=(UserControl1)obj;

Canvas can=(Canvas)VisualTreeHelper.GetParent(ctr);

List lstCtrTemp=dicCanPairedUCList[can];

if(bIsNearIns){ //若是就近插入逻辑

for(i=0;i

{/*dtemp用于保存受拖动控件与组内各控件的距离;

距离最小的控件序号将保存在变量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{//空位侧优先插入逻辑直接采用Lambda表达式完成冒泡排序

lstCtrTemp.Sort((ctr1,ctr2)=>{

return(double)ctr1.GetValue(Canvas.LeftProperty) <

(double)ctr2.GetValue(Canvas.LeftProperty) ? -1:1;});

}

//交换业务逻辑从略

……

//创建故事板实例sb并行管理一组色相子的归位动画

Storyboard sb=new Storyboard();

for(i=0;i

{ //将标准X坐标赋给各色相子控件的ToLeft

lstCtrTemp.ElementAt(i).ToLeft=lstXPos.ElementAt(i);

//横坐标归位动画

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);

//纵坐标归位动画与横坐标相类,代码从略

……

}

//动画时长设置为0.1秒,以免拖延操作时间

sb.Duration=TimeSpan.FromSeconds(0.1);

//动画结束清理工作函数提交给故事板结束事件委托

sb.Completed+=storyboard_Completed;

sb.Begin();

storyboards.Add(can,sb);//将面板与动画配对加入字典

}

//动画结束时将被执行的清理函数

privatevoidstoryboard_Completed(objectsender,EventArgse)

{

//由结束的故事板时间线对象查找受控色相子的父面板及其配对列表容器、配对故事板实例

ClockGroupclockGroup=(ClockGroup)sender;

UserControl1ctrTemp=(UserControl1)Storyboard.GetTarget(

(AnimationTimeline)clockGroup.Children[0].Timeline);

Canvascan=(Canvas)VisualTreeHelper.GetParent(ctrTemp);

Listlstctr=dicCanPairedUCList[can];

Storyboardstoryboard=storyboards[can];

//停止、清除动画,并将面板、动画配对从字典中删除

storyboard.Stop();

storyboard.Children.Clear();

storyboards.Remove(can);

foreach(UserControl1ctrinlstctr)

{ //逐一将同组各色相子的目标位置赋予自身的实际位置属性

ctr.SetValue(Canvas.LeftProperty,ctr.ToLeft);

ctr.SetValue(Canvas.TopProperty,ctr.ToTop);

ctr.IsPressed=false; //清除控件拖放状态标志,去除层次效果

Canvas.SetZIndex(ctr,1); //恢复控件初始层次

}

}

//PreDrag函数在Xmal声明中关联到控件拖放行为的PreDrag事件

privateboolPreDrag(objectsender)

{

UserControl1ctr=(UserControl1)sender;

//检查色相子控件的父面板是否处于动画状态

boolbTemp=storyboards.ContainsKey(((Canvas)ctr.Parent)) ?false:true;

if(bTemp) {//不在动画状态即将进入拖放操作

Canvas.SetZIndex(ctr, 2);//提升控件叠放层次

ctr.IsPressed=true;//设置拖放标志,触发层次特效

}

returnbTemp;

}

}

为色相子控件定义的ToLeft、ToTop依赖项属性作用在故事板中得到体现。如果不这样设计,就需要在主窗体中为全部色相子定义相应的依赖项属性数组,那样代码逻辑显然要混乱很多,并且当界面色相子控件数量发生变化时,也会带来代码维护上的不便。

本例中用到了Dictionary、List两种泛型容器,带来的好处有两方面。首先,虽然ArrayList类可以实现与泛型类相似的功能,但泛型实例是强类型的,即在声明时必须给定容器内将要存储的对象类型,从而省去了ArrayList类应用时对未知数组元素的装箱/拆箱操作,提高程序运行效率;其次,泛型类直接或间接提供了对数组元素的查询、定位、插入、排序等丰富的成员函数或接口,在程序设计方面带来的便利是显而易见的。

3.4 与分辨率无关的自适应界面设计

对于Win32应用来说,控件随着界面的大小而自动缩放是一项繁琐的任务。但由于WPF强大的布局设计与图形化界面功能,这几乎不算一个问题。如图3中的可视化树所示,将面板包含在Viewbox中,并根据需要设置Viewbox的Stretch、StretchDirection属性,就可以实现控件随用户界面大小而自适应地动态调整自身大小,满足用户的视觉需求。如图5所示,对比标题栏大小可见两个不同大小窗口中,控件完全随着窗体的拉伸自适应缩放并调整布局绘制,不需要任何后台代码。

图5 仿真色相子界面自适应缩放及布局

这种与界面大小无关的控件自适应缩放与自动布局充分体现了WPF的强大,其将编程人员从繁琐的界面布局逻辑中完全解放出来,从而可以更加专注于核心业务代码设计,对于程序开发效率和用户体验的提升具有划时代的意义。

4 结束语

根据Farnsworth-Munsell色相测试系统实物使用特点及原有软件的不足之处,文中提出了基于WPF技术的色相子仿真交互界面设计方案。该方案充分利用到.Net的图形界面优势,综合运用依赖项属性、触发器、故事板、泛型等.Net和WPF的优势特性,具有界面外观可拓展性强、更接近实际物理特性的层次效果和仿真排序过渡动画、与分辨率无关的界面自适应缩放与布局调整等特点,并对涉及的关键技术进行了详细介绍。在Win32应用逐渐落伍,个性化、富媒体化跨平台应用日益崛起的大背景下,文中介绍的.Net框架下的WPF相关技术,对于图形化界面与人机交互类的应用开发都有一定的借鉴意义。文中示例在Windows XP系统Visual Studio 2010 C#开发环境下编译,Win XP、Win 8操作系统测试通过。

[1] Troelsen A.C#与.Net 4高级程序设计[M].朱 晔,肖 逵,姚琪琳,等,译.第5版.北京:人民邮电出版社,2011.

[2] MacDonald M.WPF编程宝典—C#2010版[M].王德才,译.北京:清华大学出版社,2011.

[3] Petzold C.Windows Presentation Foundation程序设计指南[M].蔡学镛,译.北京:电子工业出版社,2008.

[4] 王 鹏,崔 静.新一代界面技术WPF的架构及应用[J].成都纺织高等专科学校学报,2011,28(1):18-20.

[5] 张京明,曹国忠,张承业,等.创新方法与交互设计结合的探讨[J].价值工程,2012,31(10):10-11.

[6] 李 颖.基于WPF的课堂教学管理系统研究与设计[J].中国教育技术装备,2011(24):85-87.

[7] 袁云云,周之昊.基于WPF的医疗辅助软件设计与开发[J].数字技术与应用,2012(2):132-132.

[8] 李成刚,冯 静,凌 玲.基于WPF的交互式绘图系统的开发[J].微型机与应用,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项目设计基础[M].北京:清华大学出版社,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

时间:2016-01-04

国家自然科学基金青年项目(81202178/H2602);全军医药卫生重大项目(AWS12J003)

李晓京(1975-),男,高级实验师,硕士,研究方向为计算机应用、生物医学工程;马 进,副研究员,博士,研究方向为心理学;胡文东,研究员,硕士,研究方向为心理学、医学工程。

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.035

猜你喜欢

色相控件鼠标
Progress in Neural NLP: Modeling, Learning, and Reasoning
高效液相色谱在食品安全检测中的应用
关于.net控件数组的探讨
色相、心相与舞台造型——民国京剧批评中的“扮相”品评
高支纱羊绒衫缩水率问题的试验分析
ASP.NET服务器端验证控件的使用
八面观音 色相俱足——天一阁藏文徽明小楷《岳阳楼记》解析
基于嵌入式MINIGUI控件子类化技术的深入研究与应用
45岁的鼠标
超能力鼠标