65.9K
CodeProject 正在变化。 阅读更多。
Home

健康和安全管理系统 - 使用 LightSwitch 创建

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (18投票s)

2011年12月8日

CPOL

7分钟阅读

viewsIcon

62580

一个用 LightSwitch 创建的健康和安全管理系统

大家好!作为 LightSwitch Star 竞赛不断增长的参与者之一,这是我提交的 LightSwitch 可能性示例。希望您能在这里找到一些有用的信息,或者至少受到启发,亲自尝试 LightSwitch。

享受吧...

健康与安全管理系统

使用 Microsoft Visual Studio LightSwitch 创建的解决方案。

Sample Image - maximum width is 600 pixels

引言

您的应用程序/扩展程序做什么?它解决了什么业务问题?

健康与安全管理系统是一个应用程序,用于帮助组织更好地管理和缓解健康与安全统计数据和 KPI。该解决方案旨在为用户提供一个工具,用于捕获和报告细粒度的健康与安全绩效指标。

工作场所安全在许多组织中扮演着越来越重要的角色。公司现在不仅要对其内部利益相关者(如员工和股东)负责,还要对其外部利益相关者(如客户、供应商和分包商)负责。无论是出于内部企业健康与安全考虑,还是出于绩效指标(如 KPI),组织都越来越重视健康与安全问题。

公司现在要求其合作伙伴提供健康与安全责任,通常在建立合作关系之前。例如,大型能源行业公司规定其供应商必须制定健康与安全计划,并妥善记录和报告。通常,这些合作关系包括合同义务,要求供应商提供定期的健康与安全报告;尤其是在客户工作现场开展工作时。

健康与安全管理系统旨在为组织提供捕获和报告关键健康与安全指标的手段。健康与安全管理系统的主要价值主张包括:

  • 细粒度的健康与安全信息收集,例如:
    • 观察 - 捕获识别健康与安全威胁和机遇的数据,
    • 未遂事故 - 发生但未导致人身伤害或工时损失的事故,以及
    • 人身伤害和工时损失事故 - 管理有关人身伤害和工时损失的详细信息。
  • 灵活直观的用户可配置报告,包括:
    • 多个“预设”和内置报告,可选择打印或导出为各种格式,如 Excel 或 PDF。
    • 强大且高度可定制的 OLAP 分析。
    • 灵活的用户定义查询,可选择保存、重新加载、打印或导出。
  • 高度可配置,并且易于为每个客户定制。
  • 可与现有组织系统快速集成;例如,旧版客户或人力资源 ERP 系统。
  • 可部署到桌面、Web 或云端。

这个应用程序有多少屏幕和实体?

目前,健康与安全管理系统有:

  • 19 个屏幕,提供标准数据输入界面以及各种管理任务(如查找或参考表、报告和分析以及安全性)的功能,以及
  • 23 个实体(表)

LightSwitch 为您的业务节省了资金吗?如何节省?

LightSwitch 提供了一种快速构建解决方案的方法。解决方案的质量与企业级解决方案的质量相匹配,而使用其他更常见的技术创建该解决方案将需要更多的时间和精力。

快速上市是关键,产品的质量也同样重要。通过 LightSwitch,可以使用技术和经过验证的软件开发最佳实践创建解决方案。LightSwitch 自动为解决方案应用质量。使用基于模板的任务可以轻松实现场景和需求。

如果您没有 LightSwitch,这个应用程序还会被构建出来吗?如果会,用什么构建?

在考虑用于解决方案的技术之前,解决方案概念就已经摆在桌面上。当时考虑使用一种或多种技术,包括:ASP.Net MVC、HTML5/JSON、SQL Server 和 WCF。

再次强调,如前所述,LightSwitch 极大地加快了交付时间。使用相对传统的开发技术将导致在满足需求之前需要更多时间。

这个应用程序支持多少用户?

按需部署。目前没有已知的限制表明该解决方案无法部署在大型企业中。

使用 LightSwitch 构建此应用程序实际花了多长时间?

截至本文撰写之时,该解决方案仅用了几天时间就构建完成。预计实际总工时为 18 小时。

此应用程序是否使用任何 LightSwitch 扩展?如果使用,是哪些?您自己编写过这些扩展吗?如果编写过,是否公开发布?在哪里?

健康与安全管理系统使用了许多扩展和自定义控件。其中包括:

开发此解决方案的一个关键成功因素是尽可能利用现有的扩展和工具。目标是尽快满足需求。使用现有工具提供了无需“重新造轮子”即可实现场景的机会。

LightSwitch 如何让您的开发人员生活更好?与您考虑过的其他选项相比,构建速度是否更快?

LightSwitch 在将 LightSwitch 用于此解决方案时,对开发人员体验产生了显著影响。投入的精力和时间比使用其他考虑过的技术要少得多。

链接、截图、视频

链接

屏幕截图

Home Page

健康与安全管理主页

Observations

新观察条目

Injury and Time Loss

人身伤害和工时损失

Reporting

报告示例

Analytics

一些非常灵活的数据挖掘功能...

Analytics

...带可视化效果!

User Defined Queries

直观的用户定义查询,可保存和加载以供日后使用。

Scheduling

调度功能,例如尾板安全会议。

至于编码和技术,这里有一些您可能觉得对您自己的 LightSwitch 项目有用的提示和技巧...

图像和图标

为应用程序应用图像和图标,为应用程序的整体外观增添了一些用户体验吸引力。用于将图像添加到应用程序中每个屏幕的标题的过程包括:

  1. 为屏幕标题图像创建适当大小的 .png 图像。
  2. 打开解决方案资源管理器文件视图。
  3. 将图像作为嵌入资源添加到客户端项目的 Resources 文件夹中。

    Screen Header Images

  4. 将图像控件添加到屏幕元素树。在此应用程序中,该元素是 SilverLight 图像控件,因此该元素将无边框...

    Screen Header Images

  5. 在客户端项目的 UserCode 文件夹中创建了一个名为 MyImageHelper 的类(在文件视图中打开解决方案资源管理器)。这用于提供少量基础结构,以使用嵌入式资源图像文件。
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.IO;
    using System.Reflection;
    using System.Windows.Media.Imaging;
    
    namespace LightSwitchApplication
    {
        public class MyImageHelper
        {
            public static byte[] GetImageByName(string fileName)
            {
                Assembly currentAssembly = Assembly.GetExecutingAssembly();
                Stream stream = currentAssembly.GetManifestResourceStream
                ("LightSwitchApplication.Resources." + fileName);
                return GetStreamAsByteArray(stream);
            }
    
            public static BitmapImage GetBitmapImageByName(string fileName)
            {
                Assembly currentAssembly = Assembly.GetExecutingAssembly();
                Stream stream = currentAssembly.GetManifestResourceStream
                ("LightSwitchApplication.Resources." + fileName);
                return GetBitmapImage(GetStreamAsByteArray(stream));
            }
    
            private static byte[] GetStreamAsByteArray(System.IO.Stream stream)
            {
                if (stream != null)
                {
                    int streamLength = Convert.ToInt32(stream.Length);
                    byte[] fileData = new byte[streamLength];
                    stream.Read(fileData, 0, streamLength);
                    stream.Close();
                    return fileData;
                }
                else
                {
                    return null;
                }
            }
    
            private static BitmapImage GetBitmapImage(byte[] bytes)
            {
                // Create a BitmapImage from a byte[];
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    var bi = new BitmapImage();
                    bi.SetSource(ms);
                    return bi;
                }
            }
        }
    }
  6. 然后回到主页屏幕,实现了代码以检索和使用屏幕上的图像...
    partial void AllIncidents_InitializeDataWorkspace(List<idataservice> saveChangesTo)
       {
           IContentItemProxy logo = this.FindControl("HomeHeaderLogo");
           logo.ControlAvailable += new EventHandler
        <controlavailableeventargs>(HomeHeaderLogo_ControlAvailable);
       }
    
    void HomeHeaderLogo_ControlAvailable(object sender, ControlAvailableEventArgs e)
       {
           // Set image source to PNG logo.
           var img = e.Control as Image;
           if (img != null)
             img.Source = MyImageHelper.GetBitmapImageByName("HealthAndSafetyLogo.png");
       }</controlavailableeventargs> </idataservice>
  7. ...当应用程序打开屏幕时应用图像...

    Screen Header Images

其他技术

此解决方案中应用的其他一些技术包括:

  • 中间或“虚拟”屏幕 - 观察、未遂事故和人身伤害事故实际上都是 Incident 实体的一种类型。当单击主页列表中任何事故的超链接时,应用了逻辑,以便根据所选事故的类型,应用程序将打开相应的事故类型屏幕。
  • 一个详细信息屏幕用于添加或编辑 - 单个屏幕用于添加和编辑实体。这是通过向屏幕添加一个参数来实现的,通常是一个表示实体 ID 的整数参数。屏幕上的逻辑将解释应用程序是为新记录还是现有记录打开屏幕。例如...
    partial void InjuryIncidentScreen_InitializeDataWorkspace
        (List<idataservice> saveChangesTo)
    {
    
      Incident incident;
      if (!this.IncidentID.HasValue)
      {
       incident = new Incident();
    
      IncidentType incidentType = (from it in DataWorkspace.ApplicationData.IncidentTypes
                                    where it.IncidentTypeName == "Injury"
                                    select it).FirstOrDefault();
    
       incident.IncidentType = incidentType;
       incident.HoursLost = 0;
    
       this.IncidentProperty = incident;
    
      }
      else
      {
        int incidentId = (int)this.IncidentID;
    
        incident = (from i in DataWorkspace.ApplicationData.Incidents
                    where i.Id == incidentId
                    select i).FirstOrDefault();
    
                    this.IncidentProperty = incident;
       }
    
    }</idataservice>

希望大家觉得这有帮助和有用。干杯!

在我们的 Facebook 页面上发布此竞赛条目的链接 到我们的 Facebook 页面,让大家知道他们应该给这份提交打分!并且不要忘记 在 Twitter 上关注我们 以获取竞赛更新!祝你好运!

© . All rights reserved.