最近做了一個備件倉庫管理軟體,雖然隻是一個不太複雜的倉庫管理業務的軟體,附帶産出一些相關的報表,而且有之前做過的送水管理系統、酒店管理系統等軟體的基礎及技術儲備,不過做起來發現還是有很多細節及新的東西,在客戶不斷提出修改意見以及改進建議的同時,逐漸吸收優化新的知識,現大概總結一些相關的開發心得,以飨讀者。
首先來看看整個軟體的主體界面,如下所示,軟體的功能主要集備件資訊管理、備件入庫、備件出庫、庫存查詢、庫房管理、業務報表、權限管理、資料字典管理、備件及庫存導入等功能于一體。

現大緻就主體界面介紹一些相關的知識:
3、 盡可能使用已經在共享軟體中廣泛性使用我自己的分頁控件,該分頁控件內建了資料分頁、内容提示、資料列印、資料導出、表頭中文轉義等很多功能,由于內建性很好,省卻很多功夫,專注客戶的業務及變化即可,否則一項表頭的中文轉換就夠嗆,還不說資料的分頁,由于整合性、一緻性、穩定性等特點,客戶使用感覺比較好。最新的版本整合了優秀的Aspose.Cell控件來進行Excel資料的導出,速度非常快,而且預設表頭當機,非常友善。
4、 使用Apose.Cell控件的強大功能,實作自定義模闆報表的定制導出。
其他設計模闆如下所示:
實際生成的報表如下所示:
5、利用現成獨立的資料字典子產品代碼。由于一般複雜一點的系統,都需要有資料字典的子產品,由于我在較早已經在這塊已經做了一些開發,是以直接拿過來使用即可,該資料字典子產品功能相對比較獨立,是以是一個非常使用的子產品,資料通過字典排序可以實作合理的排序,支援無限多級字典分類。
實際使用的時候,也是非常友善,首先我們封裝一下擷取字典項目的方法如下所示:
/// <summary>
/// 根據字典類型擷取對應的CListItem集合
/// </summary>
/// <param name="dictTypeName"></param>
/// <returns></returns>
public static CListItem[] GetDictByDictType(string dictTypeName)
{
List<CListItem> itemList = new List<CListItem>();
Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName);
foreach (string key in dict.Keys)
{
itemList.Add(new CListItem(key, dict[key]));
}
return itemList.ToArray();
}
然後再窗體初始化的時候,添加字典的初始化代碼即可,如下所示:
private void InitDictItem()
this.txtManufacture.Items.Clear();
this.txtManufacture.Items.AddRange(DictItemUtil.GetDictByDictType("供貨商"));
this.txtBigType.Items.Clear();
this.txtBigType.Items.AddRange(DictItemUtil.GetDictByDictType("備件屬類"));
this.txtItemType.Items.Clear();
this.txtItemType.Items.AddRange(DictItemUtil.GetDictByDictType("備件類别"));
this.txtUnit.Items.Clear();
this.txtUnit.Items.AddRange(DictItemUtil.GetDictByDictType("機關"));
this.txtSource.Items.Clear();
this.txtSource.Items.AddRange(DictItemUtil.GetDictByDictType("來源"));
this.txtUsagePos.Items.Clear();
this.txtUsagePos.Items.AddRange(DictItemUtil.GetDictByDictType("使用位置"));
this.txtUsagePos.SelectedIndex = 0;
this.txtBelongDept.Items.Clear();
this.txtBelongDept.Items.AddRange(DictItemUtil.GetDictByDictType("部門"));
this.txtBelongWareHouse.Items.Clear();
this.txtBelongWareHouse.Items.AddRange(Portal.gc.ManagedWareHouse.ToArray());
this.txtBelongWareHouse.SelectedIndex = 0;
}
通過資料字典大類無限級分類以及對字典内容的管理,基本上可以滿足絕大多數的需要。
6、使用獨立又具整合性的權限管理系統,既互相獨立,有互相整合,友善重用,又不需重新開發,非常友善、更提高效率。 由于權限系統精簡而又能滿足日常絕大多數的需要,不會複雜的難于管理,而且也是基于角色的授權通路機制(RBAC),最重要是非常适合軟體的整合使用。
使用者角色功能維護界面如下:
編輯角色對應的權限界面如下:
如果我們在開發的系統中要內建現有的權限系統,操作代碼如下所示:
/// <summary>
/// 從資料庫中列出相關使用者
private void InitLoginName()
User userBLL = new User();
List<UserInfo> userList = userBLL.GetAll();
this.cmbzhanhao.Items.Clear();
foreach (UserInfo info in userList)
this.cmbzhanhao.Items.Add(info.Name);
}
登入的時候,隻需要把該客戶能操作的功能點放到記憶體清單中,如下所示:
string loginName = this.cmbzhanhao.Text.Trim();
User userBLL = new User();
string identity = userBLL.VerifyUser(loginName, this.tbPass.Text, Guid.NewGuid().ToString());
if (!string.IsNullOrEmpty(identity))
{
UserInfo info = userBLL.GetUserByName(loginName);
#region 擷取使用者的功能清單
Function functionBLL = new Function();
List<FunctionInfo> list = functionBLL.GetFunctionsByUser(info.ID, "WareMis");
if (list != null && list.Count > 0)
{
foreach (FunctionInfo functionInfo in list)
{
if (!Portal.gc.FunctionDict.ContainsKey(functionInfo.ControlID))
{
Portal.gc.FunctionDict.Add(functionInfo.ControlID, functionInfo);
}
}
}
#endregion
}
使用者對某個功能點授權判斷,隻需要判斷某功能點是否在已有集合中即可,如下所示:
/// 根據權限屏蔽功能
private void InitAuthorizedUI()
this.tool_Report.Enabled = Portal.gc.HasFunction("Report");
this.tool_Dict.Enabled= Portal.gc.HasFunction("Dictionary");
this.tool_ItemDetail.Enabled = Portal.gc.HasFunction("ItemDetail");
this.tool_Purchase.Enabled = Portal.gc.HasFunction("Purchase");
this.tool_StockSearch.Enabled = Portal.gc.HasFunction("StockSearch");
this.tool_TakeOut.Enabled = Portal.gc.HasFunction("TakeOut");
this.menu_WareHouse.Enabled = Portal.gc.HasFunction("WareHouse");
this.menu_Dictionary.Enabled = Portal.gc.HasFunction("Dictionary");
this.menu_run_systemLog.Enabled = Portal.gc.HasFunction("LoginLog");
this.menu_Parameters.Enabled = Portal.gc.HasFunction("Parameters");
this.menu_MonthlyStatistic.Enabled = Portal.gc.HasFunction("MonthlyStatistic");
this.menu_AnnualStatistic.Enabled = Portal.gc.HasFunction("AnnualStatistic");
this.menu_ClearAll.Enabled = Portal.gc.HasFunction("ClearAllData");
this.menu_ImportItemDetail.Enabled = Portal.gc.HasFunction("ImportItemDetail");
是以,文章到這裡先小結一下,就是利用現有成熟、穩定、內建性好的控件或者子產品,或者利用合适易用的控件,既能事半功倍的完成任務,又能快速響應客戶的需求變化 ,還能在界面整體上給客戶留下好的印象,一舉三得,何樂不為? 歡迎與大家一起探讨Winform開發的點點滴滴或者互相合作交流。