脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

时间:2022-08-28 22:58:22

在上篇随笔《脊柱外科病人资料管理系统的界面设计分析》中介绍了一些常用的界面设计方面的内容,本篇继续上一篇,介绍脊柱外科病人管理系统的JOA评分记录模块的界面设计以及实现方面的内容。

JOA(全称 Japanese Orthopaedic Association Scores for Assessment of Cervical Myelopathy),日本骨科学会(JOA)颈椎病疗效评定标准,用于在脊柱外科的术前术后,对患者身体状况进行量化,并制定相关的护理方案提供依据。JOA评分记录模块,是软件《脊柱外科病人资料管理系统》的一个亮点,能使外科医生或者护士,对患者的信息进行全面的记录和研究参考。

1、JOA评分记录模块的分析

JOA评分记录,有点类似于考题的方式,对各项内容进行分值的评估,每项记录的得分不同,汇总成一个总的得分,用于量化评估,它的分类大致如下所示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

从上面的文档截图可以看到,评分项目可以分为一个大类(如自觉症状),多个子项目(如下腰痛)这样的组织方式,然后我们需要记录每项的得分,以及所有项目累加的总分。

通过分拆,我们可以把一个记分的题目作为一个控件,每个题目它自己的得分明细可以动态从数据库获取即可,界面控件设计如下所示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

通过上面的分析,我们知道,一个项目大类(如自觉症状)包含了多个子项目(如下腰痛、步态等)这样的题目,也就是多个上面控件的实例,那么我们设计的项目大类控件界面如下所示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

以上的界面,其实就是在一个大的项目大类控件上组合多个子项目控件的效果。

然后,整个JOA评分的界面就是多个上面项目大类的组合了,组合成了一个JOA评分记录模块的控件效果,如下所示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

最后,我们在第一个文档截图里面看到,JOA评分分为两个方面,一个是术前的,一个是术后的,他们的评分界面完全一样,那么我们可以把它们用两个Tab界面进行分开处理,最后得到的运行界面如下所示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

2、JOA评分记录的逻辑实现

为了在界面呈现各项分数项目,我们需要在数据库设计一个表JOAItem,用来存储每个评分项目的内容,然后在界面中根据分类进行动态展示。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

然后定义一个评分子项目的信息对象ControlItem,作为上面控件的信息对象,方便控件和数据库关联起来,记分或者存储明细到数据库中,代码如下所示。

    /// <summary>
/// JOA评分项目明细
/// </summary>
[DataContract]
public class ControlItem
{
/// <summary>
/// 序号,从1开始
/// </summary>
[DataMember]
public virtual int Seq { get; set; } /// <summary>
/// 分类名称
/// </summary>
[DataMember]
public virtual string Category { get; set; } /// <summary>
/// 项目明细列表(包括项目得分等信息)
/// </summary>
[DataMember]
public virtual List<JOAItemInfo> ItemList { get; set; } /// <summary>
/// 评分项目第一项得分(默认得分)
/// </summary>
public virtual decimal DefaultScore
{
get
{
if (ItemList == null || ItemList.Count == )
{
return 0M;
}
else
{
return ItemList[].Score;
}
}
} /// <summary>
/// 默认构造函数
/// </summary>
public ControlItem()
{
ItemList = new List<JOAItemInfo>();
} /// <summary>
/// 参数构造函数
/// </summary>
/// <param name="seq">序号</param>
/// <param name="category">分类名称</param>
/// <param name="itemList">项目明细列表</param>
public ControlItem(int seq, string category, List<JOAItemInfo> itemList) : this()
{
this.Seq = seq;
this.Category = category;
this.ItemList = itemList;
}
}

在上面的评分控件中,我们整合以上的信息对象作为一个整体,部分代码如下所示。

    public partial class ScoreItemControl : DevExpress.XtraEditors.XtraUserControl
{
/// <summary>
/// 单项的序号,从1开始
/// </summary>
public int Seq = ; /// <summary>
/// 控件绑定的信息
/// </summary>
public ControlItem ControlItem { get;set; } /// <summary>
/// 单项的得分
/// </summary>
public decimal Score { get; set; } /// <summary>
/// 处理分数变化后的事件触发
/// </summary>
public event ScoreChangedHandler OnScoreChanged; ............................

当我们在评分控件中指定了ControlItem信息后,在控件的Load事件里面,将会动态绑定评分的项目明细,代码如下所示。

        private void ScoreItemControl_Load(object sender, EventArgs e)
{
if (ControlItem != null && !this.DesignMode)
{
this.lblItemIndex.Text = ControlItem.Seq.ToString();
this.layoutItem.Text = ControlItem.Category; List<CListItem> itemList = new List<CListItem>();
foreach (JOAItemInfo info in ControlItem.ItemList)
{
itemList.Add(new CListItem(info.ItemDetail, info.Score.ToString()));
} radItemGroup.BindDictItems(itemList);
} if (radItemGroup.Properties.Items.Count > )
{
this.radItemGroup.SelectedIndex = ;
}
}

除了ControlItem信息对象的绑定,我们还注意到上面的OnScoreChanged事件,它就是为了我们在整个控件中实现分数动态变化的一个事件,这样我们变化任何一个评分项目信息,单项分数和总分都会重新计算一次的事件。

        /// <summary>
/// 处理分数变化后的事件触发
/// </summary>
public virtual void ProcessScoreChanged(int seq, decimal score)
{
if (OnScoreChanged != null)
{
OnScoreChanged(seq, score);
}
} private void radItemGroup_SelectedIndexChanged(object sender, EventArgs e)
{
this.lblItemScore.Text = string.Format("得分({0})分", this.radItemGroup.EditValue); decimal result = ;
if (decimal.TryParse(this.radItemGroup.EditValue.ToString(), out result))
{
this.Score = result;
ProcessScoreChanged(Seq, result);
}
}

以上代码逻辑就是最小评分控件的一个具体的实现,完成以上这些,还需要完成一个评分项目大类的具体逻辑,它的操作方式和上面差不多,也是引入一个信息对象集合作为背后得分计算的逻辑。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现

定义的信息对象ProjectItem代码如下所示。

   /// <summary>
/// JOA评分项目信息
/// </summary>
[DataContract]
public class ProjectItem
{
/// <summary>
/// 序号,从1开始
/// </summary>
[DataMember]
public virtual int Seq { get; set; } /// <summary>
/// 项目名称
/// </summary>
[DataMember]
public virtual string Project { get; set; } /// <summary>
/// 项目明细列表
/// </summary>
[DataMember]
public virtual List<ControlItem> ItemList { get; set; } /// <summary>
/// 默认构造函数
/// </summary>
public ProjectItem()
{
ItemList = new List<ControlItem>();
} /// <summary>
/// 评分项目第一项得分总和(默认得分)
/// </summary>
public virtual decimal DefaultScore
{
get
{
if (ItemList == null || ItemList.Count == )
{
return 0M;
}
else
{
decimal total = 0M;
foreach (ControlItem item in ItemList)
{
total += item.DefaultScore;
}
return total;
}
}
} /// <summary>
/// 参数化构造函数
/// </summary>
/// <param name="seq"></param>
/// <param name="project"></param>
/// <param name="itemList"></param>
public ProjectItem(int seq, string project, List<ControlItem> itemList) : this()
{
this.Seq = seq;
this.Project = project;
this.ItemList = itemList;
}
}

然后该控件的逻辑代码就是结合这个信息对象以及控件的一些事件进行处理了,控件的部分代码如下所示。

    public partial class ScoreProjectControl : DevExpress.XtraEditors.XtraUserControl
{
/// <summary>
/// 项目大类的序号,从1开始
/// </summary>
public int ProjectSeq = ; /// <summary>
/// 项目大类的信息
/// </summary>
public ProjectItem ProjectItem { get; set; } /// <summary>
/// 处理分数变化后的事件触发
/// </summary>
public event ScoreChangedHandler OnScoreChanged; private Dictionary<int, decimal> scoreList = new Dictionary<int, decimal>();//记录单项的得分列表 ...................

由于每项评分子项目是单独的评分控件,控件的布局采用了FlowLayout布局呈现方式,因此在控件的Load事件代码如下所示。

        private void ScoreProjectControl_Load(object sender, EventArgs e)
{
if (ProjectItem != null && !this.DesignMode)
{
this.lblProject.Text = string.Format("{0}、{1}", ProjectItem.Seq, ProjectItem.Project); this.flowLayoutPanel1.Controls.Clear();
int index = ;
foreach (ControlItem item in ProjectItem.ItemList)
{
ScoreItemControl control = new ScoreItemControl();
control.ControlItem = item;
control.Seq = index++;
control.OnScoreChanged += new ScoreChangedHandler(control_OnScoreChanged);
this.flowLayoutPanel1.Controls.Add(control);
}
}
}

同样整个控件也有一个OnScoreChanged 的事件,我们看到,这个和上面介绍的事件操作方式类似,都是一级负责一级的分数处理,具体代码如下所示。

        void control_OnScoreChanged(int seq, decimal score)
{
if(!scoreList.ContainsKey(seq))
{
scoreList.Add(seq, score);
}
else
{
scoreList[seq] = score;
} //项目的总分变化
ProcessScoreChanged(ProjectSeq, this.TotalScores);
}

以上的控件实现逻辑一步步递推,就能很好实现评分项目的动态呈现,以及控件评分分数的动态变化和总分记录保存,由于涉及的实现细节还比较多,一篇随笔介绍内容太多显得累赘,但是其他控件的实现逻辑和上面的操作方式差不多,在这里就不在一一赘述了,本文主要提供一个这种的实现思路进行JOA评分记录模块的实现,进一步拓展,可以把它应用到考试题目上 ,可以作为动态抽取题目,然后记录测试者的题目选择信息,最后把测试者的答案和标准答案对比得出用户的总分,这样就完成了试题的动态测试案例了。

脊柱外科病人资料管理系统的界面设计分析(2)--JOA评分记录的实现的更多相关文章

  1. HTML5&plus;规范:nativeUI&lpar;管理系统原生界面&rpar;

    nativeUI管理系统原生界面,可用于弹出系统原生提示对话框窗口.时间日期选择对话框.等待对话框等. 1.方法 1.1.actionSheet: 弹出系统选择按钮框 void plus.native ...

  2. WPF软件开发系统之四——医疗病人信息管理系统

    仿360悬浮窗的方式,始终有个工具栏浮在桌面的最顶层,方便任何时候操作. 主要功能包括:病人信息的添加.修改.查询.包括别人基本信息.诊断结果.接待医生.手术多张图片等. 系统特点:简洁.易操作.美观 ...

  3. Qt编写气体安全管理系统(界面超漂亮)

    自从把Qt样式表葵花宝典这个pdf文件看完以后,将所有的qss内容都轮了一遍,还写了个皮肤生成器工具,https://blog.csdn.net/feiyangqingyun/article/deta ...

  4. 在EF的code frist下写稳健的权限管理系统:界面设计(四)

    基本都是采用pure设计(中文官网:http://purecss.org,英文官网:http://purecss.io).pure只是一个简单强大的cssUI库,支持响应式设计,适合自己设计或者给美工 ...

  5. 黑色的网站后台管理系统ui界面——后台

    链接:http://pan.baidu.com/s/1pLffwE3 密码:m4v6

  6. Docker集中化web界面管理平台-Shipyard部署记录

    Docker图形页面管理工具基本常用的有三种: DOCKER UI,Shipyard,Portainer.对比后发现,Shipyard最强大,其次是Portainer,最后是Docker ui.之前介 ...

  7. Django项目:CRM&lpar;客户关系管理系统&rpar;--68--58PerfectCRM实现king&lowbar;admin批量生成上课记录

    # kingadmin.py # ————————04PerfectCRM实现King_admin注册功能———————— from crm import models #print("ki ...

  8. Django项目:CRM&lpar;客户关系管理系统&rpar;--67--57PerfectCRM实现admin批量生成上课记录

    #admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...

  9. Winform开发框架之通用高级查询模块

    最近一直忙于公司的事情,虽然一直在做一些相关的技术研究,但是很久没能静下心来好好写写博客文章了,想想也有半个月之多了,这半个月来,也一直致力于改善我的WInform开发框架,使得自己及客户使用起来更加 ...

随机推荐

  1. Maven Scope

    Dependency Scope  在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署.目前<scope>可以使用5个值:  * ...

  2. Objective-C语言控制语句

    • 分支语句• 循环语句• 跳转语句 Objective-C中的控制语句有以下几类:• 分支语句:if-else, switch• 循环语句:while, do-while, for• 与程序转移有关 ...

  3. 2013 Multi-University Training Contest 2

    HDU-4611 Balls Rearrangement 题意:具体题意不大清楚,最后要处理一个这样的表达式:sum{ |i % a - i % b| },0 <= i < N 的取值很大 ...

  4. Flood-it&excl;

    Flood-it! 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4127/http://acm.split.hdu.edu.cn/showproble ...

  5. CDialog上使用CToolBar&plus;CReBar

    最经在做一些用户界面的东西,对话框上有很多按钮和组合框,全部加起来差不多有20多个吧,界面非常凌乱,最后决定用CToolBar + CReBar来重新设计界面,为什么选用这个呢?一是因为看到IE用的也 ...

  6. 关于配置Tomcat的URIEncoding

    遇到的问题: 程序需要发送http GET请求到服务器,请求的参数中包含了中文字符.程序中参数为UTF-8格式,且经过了UTF-8 URL编码再发送.使用的tomcat服务器,但服务器端后台程序中取到 ...

  7. 多线程&plus;socket实现多人聊天室

    最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo: demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消 ...

  8. jmeter 脚本规范

    总结了一下公司正在用 jmeter 脚本规范. 使用 jmeter 进行接口级测试, 随着接口增多以及业务逻辑越来越复杂, 导致 jmeter 脚本的维护会更加困难.针对实际使用中发现的问题进行一些规 ...

  9. linux中~&sol;cut&sol;argus&sol;

    1.Linux shell 截取字符变量的前8位 实现方法有如下几种: expr substr "$a" 1 8 echo $a|awk '{print substr(,1,8)} ...

  10. jQuery之animate&lpar;&rpar;用法

    最近在学习jQuery,看到一个很有意思的函数animate(),但是在网上却没有查到相关的详细资料,于是打算参考jQuery API,自己总结一下. 概述 animate() 方法执行 CSS 属性 ...