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

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

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

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

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

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

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

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

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

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

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

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

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

然后定义一个评分子项目的信息对象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 == 0)
                {
                    return 0M;
                }
                else
                {
                    return ItemList[0].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 = 1;

        /// <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 > 0)
            {
                this.radItemGroup.SelectedIndex = 0;
            }
        }

除了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 = 0;
            if (decimal.TryParse(this.radItemGroup.EditValue.ToString(), out result))
            {
                this.Score = result;
                ProcessScoreChanged(Seq, result);
            }
        }

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

定义的信息对象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 == 0)
                {
                    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 = 1;

        /// <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 = 1;
                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评分记录的实现,如需转载请自行联系原博主。

时间: 2024-11-28 23:19:13

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

脊柱外科病人资料管理系统的界面设计分析

在平常的学习研究中,或者有时候因为开发项目的各种需要,会对界面设计进行各种方式的改良尝试 ,遇到好的经验实践,就一直在我自己的各种项目中沿用下去,本文主要分析我的一款病人资料管理系 统-脊柱外科病人资料管理系统的系统界面设计,以及如何基于DevExpress控件的具体实现,从而为用户 提供更好的界面效果体验. 1.系统主体界面设计 系统主体界面设计,遵循我的<WInform开发框架>的技术特点,使用基于Ribbon样式的多文档布局 界面框架,通过在主工具栏里面对功能进行分类,实现更多的功能点排

一个缺陷管理系统数据库设计和界面设计分析

在Winform方面,基于业务的不同,我们可以利用工具的效率,快速做很多不同的业务系统,前期做了一个缺陷管理系统,想把单位的测试业务规范下,也好统计和分析每个版本的缺陷信息,本篇整理这些数据库设计和界面设计的相关内容,做一个介绍,希望给大家一个对比参照的案例进行学习了解. 1.缺陷管理系统的业务分析 在很多缺陷管理系统里面,我们往往需要管理的就是缺陷信息的记录,以及缺陷记录的开闭过程,从而实现了测试人员->开发人员->测试人员的整个闭环过程. 一般情况下,缺陷管理系统可以部署在局域网内,或者公

求研究所资料管理系统

问题描述 大家好,我正在做一个研究所资料管理系统,研究所资料包括图书,期刊,论文和产品说明书,希望大家提供这方面的资料,先在这里谢谢大家了! 解决方案 解决方案二:很多解决方案三:没看到研究所的,有客户的等解决方案四:支持一下解决方案五:谢谢大家的帮助!解决方案六:其实这个资料管理系统和图书管理系统不一样,这个要管理四类资料,分别是图书,期刊,论文和产品说明书.解决方案七:最简单的东东.楼主自己做吧解决方案八:建议你看看SharePoint技术,用这个可能比较容易实现解决方案九:找找知识管理系统

c++-基于sql servser的数据库管理系统交互界面设计

问题描述 基于sql servser的数据库管理系统交互界面设计 其实想问的是在c/c++的基础上该选择怎样的交互界面设计,MFC感觉并不好- 解决方案 http://baike.sogou.com/v101857452.htm?fromTitle=MFC%09%E5%BE%AE%E8%BD%AF%E5%9F%BA%E7%A1%80%E7%B1%BB%E5%BA%93 这是MFC的介绍,你可以看看. 如果你不喜欢的话,可以纯手工自己写代码 解决方案二: 使用c/c++设计交互界面设计, 不用mf

c++-图书馆资料管理系统课设求解析

问题描述 图书馆资料管理系统课设求解析 大神帮忙解释一下课设的要求,详解,要用什么函数,初学者不对懂,求解 解决方案 这里有一个C的代码,希望可以在思路上给你帮助http://www.codeincodeblock.com/2011/03/mini-project-library-management-in-c.html 解决方案二: http://www.codeforge.cn/article/100043 看一下实例

急!!大于30000 求java编写 人力资源管理系统框架界面及数据库 。

问题描述 大于30000求java编写人力资源管理系统框架界面及数据库.需求,交易方式请看这里:http://union.zhubajie.com/?u=5161194&l=http://task.zhubajie.com/877840/

C#客户资料管理系统那位高手会呀

问题描述 利用C#基本语法知识,创建一个客户资料管理系统,实现客户资料的电子化管理.该系统设计的基本要求如下:一.本系统的主要功能模块1.添加客户信息资料模块提供添加新的客户信息资料的功能,并提供一个添加信息的窗体.2.修改客户信息资料模块提供修改客户信息资料的功能3.删除某个客户信息资料模块提供删除某个客户信息资料的功能,根据提供的编号,从计算机中删除某个客户信息资料.4.显示所有客户信息资料模块提供显示该系统中所有客户信息资料的功能5.按姓名模糊查询客户信息资料的功能提供对某个字符进行有效查

基于云存储模式的非书资料管理系统

基于云存储模式的非书资料管理系统 黄兴燕 介绍了传统的非书资料管理模式,目前光盘网络化管理模式存在的问题,以及云存储 的概念及结构模型.论述了云存储模式下的非书资料管理系统的建立和该系统的特点及优势. 基于云存储模式的非书资料管理系统

【黑马Android】(03)学生管理系统/动态刷新界面

学生管理系统 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima27.sutdentmanager" android:versionCode="1" android:versionNam