95992828九五至尊2

Metronic开发框架经验总计882828九五至尊手机版,Winform开发框架之权能管理种类革新的经验总计

二月 21st, 2019  |  882828九五至尊手机版

近日直接在做一些技术性的商讨和框架创新工作,博客也落下一些天尚未创新了,也该是时候静下心来,统计那段时间的片段技术革新的经历了。和上一阶段的CPAJEROM系统开发和技能研讨一样,小编都欢乐在一个品种依旧模块形成后,做一些休戚相关的总计性工作,记录下前一品级的技术脚印,希望给自个儿留下3个脚印快照,同时给读者精晓本人的技巧趋势外,也富有收获。本小说首要介绍在下拉列表中浮现多个列表,以便完结数据结构的可观呈现,并能快捷选定所需的节点,那些就是TreeListLookup艾德it控件的行使。

在上篇据悉BootStrap
Metronic开发框架经验总括【二】列表分页处理和插件JSTree的施用
,介绍了多少的分页处理,使用了Bootstrap
Paginator插件,其余对树形列表,接纳了JSTree插件,本篇继续介绍在编排页面中常用到的控件Select2,那一个控件可以尤其丰硕古板的Select下拉列表控件,提供越来越多的作用和更好的用户体验。

一 、界面效果显示

首先大家来看望自身的Winform开发框架之权能管理体系模块创新完善后的主界面,然后在介绍其中使用的效用点,以及技术完毕。

系统用户消息保管界面如下所示。

882828九五至尊手机版 1

内部用户音讯编辑界面如下所示。

882828九五至尊手机版 2

里面编辑用户消息的界面包涵了所属公司、所属单位、直属CEO八个输入的内容,为了削减数据量的显得,那多少个输入框是通过级联的点子展开体现,约等于说,先选定所属公司,然后在所属集团中列出该商户的机关列表,选定部门后,再经过获取内定部门的人口新闻,作为直属首席执行官的人手突显。

了解这个逻辑关系后,大家来探视所属集团的列表呈现,如下所示。

882828九五至尊手机版 3

选定了所属公司后,所属单位就依照卖家来举行过滤了,如下所示。

882828九五至尊手机版 4

由此集团和部门的尺度,大家就可以列出有限的人口列表,作为直属首席营业官的人手列表了,那个列表使用普通的下拉列表体现即可,在此不再赘言。

如上的树状结构的下拉列表,在DevExpress控件中是透过TreeListLookup艾德it控件举办落到实处的。

① 、Select2控件介绍

贰 、基于DevExpress控件的效应完成及代码突显 

 由于那么些所属公司、所属单位的成效模块,一般须要过多代码举行处理,为了更好重用那些模块,大家透过用户控件的包裹格局进行,然后在数量编辑界面上,通过拖动控件形式即可兑现布局,并只要求设置只怕访问有些属性即可,封装的用户界面控件如下所示。

882828九五至尊手机版 5

1)所属集团控件代码

所属公司是3个用户控件,让其后续自XtraUserControl即可,为了在挑选内容后触发值的变通事件,大家定义了一个轩然大波伊夫ntHandler
艾德itValueChanged,这样大家在其间控件的值变化的时候,可以通报外部的界面进行拍卖。

    public partial class CompanyControl : XtraUserControl
    {
        /// <summary>
        /// 选择的值发生变化的时候
        /// </summary>
        public event EventHandler EditValueChanged;

        public CompanyControl()
        {
            InitializeComponent();

            this.txtCompany.EditValueChanged += new EventHandler(txtCompany_EditValueChanged);
        }

        void txtCompany_EditValueChanged(object sender, EventArgs e)
        {
            if (EditValueChanged != null)
            {
                EditValueChanged(sender, e);
            }
        }

为了贯彻列表数据的绑定,以及增加图标作为有别于节点,TreeListLookup艾德it控件的数码绑定操作是以此控件的主干所在。

在上边的代码逻辑之中,咱们经过获取公司列表,然后把它转换为3个DataTable,并依据公司、公司的层系给予区其余图标,绑定数据,并安装好控件的Key菲尔德Name、ParentFieldName、ValueMember、DisplayMember多少个基本点性质即可,如下所示。

        /// <summary>
        /// 初始化数据
        /// </summary>
        public void Init()
        {
            DataTable dt = DataTableHelper.CreateTable("ImageIndex|int,ID,PID,Name");
            List<OUInfo> list = BLLFactory<OU>.Instance.GetGroupCompany();
            DataRow dr = null;
            foreach (OUInfo info in list)
            {
                dr = dt.NewRow();
                dr["ImageIndex"] = Portal.gc.GetImageIndex(info.Category);
                dr["ID"] = info.ID.ToString();
                dr["PID"] = info.PID.ToString();
                dr["Name"] = info.Name;
                dt.Rows.Add(dr);
            }



            //设置图形序号
            this.treeListLookUpEdit1TreeList.SelectImageList = this.imageList2;
            this.treeListLookUpEdit1TreeList.StateImageList = this.imageList2;

            this.txtCompany.Properties.TreeList.KeyFieldName = "ID";
            this.txtCompany.Properties.TreeList.ParentFieldName = "PID";
            this.txtCompany.Properties.DataSource = dt;
            this.txtCompany.Properties.ValueMember = "ID";
            this.txtCompany.Properties.DisplayMember = "Name";
        }

为了便于编辑界面中,对所属公司的赋值与收获操作,我们需求充实二个Text属性和二个Value属性。大家必要重载Text属性,用来收获或设置所属公司的名称;添加三个Value属性,用来得到所属公司的ID,如下所示。

        /// <summary>
        /// 公司名称
        /// </summary>
        public override string Text
        {
            get
            {
                return this.txtCompany.Text;
            }
            set
            {
                this.txtCompany.Text = value;
            }
        }

        /// <summary>
        /// 公司ID
        /// </summary>
        public string Value
        {
            get
            {
                string result = "-1";
                if (this.txtCompany.EditValue == null || this.txtCompany.EditValue.ToString() == "0")
                {
                    result = "-1";
                }
                else
                {                  
                    result = this.txtCompany.EditValue.ToString();
                }
                return result;
            }
            set
            {
                this.txtCompany.EditValue = value;
            }
        }

2)所属单位的控件代码

所属单位的代码逻辑和所属集团大多,唯一差距的是,所属单位须求1个上级的单位标识(公司ID)作为数据的过滤获取,如下所示。

        /// <summary>
        /// 初始化部门信息
        /// </summary>
        public void Init()
        { 
            //InitUpperOU
            DataTable dt = DataTableHelper.CreateTable("ImageIndex|int,ID,PID,Name,HandNo,Category,Address,Note");
            DataRow dr = null;

            if (!string.IsNullOrEmpty(ParentOuID))
            {
                List<OUInfo> list = BLLFactory<OU>.Instance.GetAllOUsByParent(ParentOuID.ToInt32());
                foreach (OUInfo info in list)
                {
                    dr = dt.NewRow();
                    dr["ImageIndex"] = Portal.gc.GetImageIndex(info.Category);
                    dr["ID"] = info.ID.ToString();
                    dr["PID"] = info.PID.ToString();
                    dr["Name"] = info.Name;
                    dr["HandNo"] = info.HandNo;
                    dr["Category"] = info.Category;
                    dr["Address"] = info.Address;
                    dr["Note"] = info.Note;
                    dt.Rows.Add(dr);
                }
            }
            //增加一行空的
            dr = dt.NewRow();
            dr["ID"] = "0"; //使用0代替-1,避免出现节点的嵌套显示,因为-1已经作为了一般节点的顶级标识
            dr["PID"] = "-1";
            dr["Name"] = "无";
            dt.Rows.InsertAt(dr, 0);

            //设置图形序号
            this.treeListLookUpEdit1TreeList.SelectImageList = this.imageList2;
            this.treeListLookUpEdit1TreeList.StateImageList = this.imageList2;

            this.txtDept.Properties.TreeList.KeyFieldName = "ID";
            this.txtDept.Properties.TreeList.ParentFieldName = "PID";
            this.txtDept.Properties.DataSource = dt;
            this.txtDept.Properties.ValueMember = "ID";
            this.txtDept.Properties.DisplayMember = "Name";
        }

3)主界面的控件使用

封装好所属集团和所属部门的控件后,大家就足以因此在工具箱里面拖动控件到主编辑界面里面去了,那样我们只须求不难对控件进行设置和赋值即可兑现,减少对控件逻辑过多的代码处理。

数码编辑界面中,控件的行使代码如下所示。

a)界面赋值操作

                    this.txtCompany.Value = info.Company_ID;
                    this.txtDept.Value = info.Dept_ID;

b)界面数据得到操作

            info.Dept_ID = txtDept.Value;
            info.DeptName = txtDept.Text;
            info.Company_ID = txtCompany.Value;
            info.CompanyName = txtCompany.Text;

c)界面事件的处理操作

出于界面上四个控件是级联的关系,因而要求处理他们控件的值暴发变化的轩然大波,如下所示。

    public partial class FrmEditUser : BaseEditForm
    {
        public FrmEditUser()
        {
            InitializeComponent();

            this.txtCompany.EditValueChanged += new EventHandler(txtCompany_EditValueChanged);
            this.txtDept.EditValueChanged += new EventHandler(txtDept_EditValueChanged);
        }

        void txtCompany_EditValueChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.txtCompany.Value))
            {
                //赋值给部门控件,并重新初始化部门列表
                txtDept.ParentOuID = this.txtCompany.Value;
                txtDept.Init();
            }
        }

        void txtDept_EditValueChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtDept.Value))
            {
                //获取所属部门后,就通过部门ID来初始化直属经理的人员列表
                InitManagers(txtDept.Value.ToInt32());
            }
        }
.................      

 

以此插件是基于Select的恢宏插件,可以提供越发丰富的职能和用户体验,它的github官网地址为:https://select2.github.io/,具体的接纳案例,可以参照地址:https://select2.github.io/examples.html

三 、基于古板Winform界面的控件完毕

上边的牵线内容是依据DevExpress的控件组进行职能完成的,有个别人大概会问,小编使用古板体制的界面控件,这种成效怎样兑现呢,其实假使是拔取内置的控件,是相比较艰苦达成这一个效果的,不过那样的界面控件有广大人付出好组件可以接纳的,作者在做那一个模块的时候,也考虑到了那或多或少,因此也本着这么些做了有的寻觅查询,发现海外有3个同行封装的控件做的那多少个不利,地址是http://www.brad-smith.info/blog/archives/477,上面的效用基本上没难点的。此人的博客和下载的事例里面,没有利用德姆o的代码,小编本人根据控件的习性举行了1个德姆o例子的编撰,效果和代码如下所示。

882828九五至尊手机版 6

全体来说,这些控件已毕的效果照旧11分不利的,例子代码如下所示,其节点和TreeView的操作看似,通过ComboTreeNode对象举办添加即可。

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!this.DesignMode)
            {
                this.comboTreeBox1.Nodes.Clear();

                ComboTreeNode parentNode = new ComboTreeNode();
                parentNode.Text = "爱奇迪集团";
                parentNode.Nodes.Add("gz", "广州分公司");
                parentNode.Nodes["gz"].ImageIndex = 1;//通过名字引用
                parentNode.Nodes["gz"].ExpandedImageIndex = 1;//通过名字引用

                ComboTreeNode bjNode = new ComboTreeNode(); 
                bjNode.Name = "bj";
                bjNode.Text = "北京分公司";
                bjNode.ImageIndex = 1;
                bjNode.ExpandedImageIndex = 1;
                bjNode.FontStyle = FontStyle.Bold;

                bjNode.Nodes.Add("财务部");
                bjNode.Nodes.Add("市场部");
                bjNode.Nodes.Add("人力资源部");

                parentNode.Nodes.Add(bjNode);
                this.comboTreeBox1.Nodes.Add(parentNode);

                comboTreeBox1.ExpandAll();
            }
        }

除去那么些可以落成古板界面效果的下拉树突显外,CodeProject上的http://www.codeproject.com/Articles/25471/Customizable-ComboBox-Drop-Down那篇文字达成的成效也还不易。

不过可能没有上面的老大效果好一些。 

我们在任何框架之中,用到了成百上千Select2控件来拍卖内容的突显,包蕴单选的下拉列表(包蕴级联选用框)、复选的下拉列表、树形下拉列表等艺术,界面效果如下所示。

4、总结

如上这一个就是关于级联下拉列表,并在下拉列表里面浮现层次关系的树形结构的作用达成和中坚代码的操作,本散文介绍了根据DevExpress样式和历史观样式二种方案的达成进度,重点对DevExpress控件中的TreeListLookup艾德it控件的兑现举行介绍,希望大家可以在骨子里工作中用上。

 

1)编辑界面下的省区、城市、所在行政区的级联界面效果,采纳省份,会加载对应省份下的都会,采取城市,会一连加载城市下的行政区,从而已毕多元关联的下拉列表效果。

882828九五至尊手机版 7

2)编辑界面下的多项采纳下拉列表

882828九五至尊手机版 8

但大家接纳其中的内容的时候,系统活动突显出从未拔取的列表数据,十分直观友好,如下所示。

882828九五至尊手机版 9

3)树形列表的下拉列表

偶尔,大家的一对数码只怕有层次关系的,如所属机构、上层列表等等。

882828九五至尊手机版 10

882828九五至尊手机版 11

882828九五至尊手机版,贰 、Select2控件的其实应用代码分析

1)基础界面代码及操作

选取select2控件,一般是在常规的select控件上,设置一下即可(设置它的class为select2)。

<div class="col-md-6">
  <div class="form-group">
    <label class="control-label col-md-4">重要级别</label>
    <div class="col-md-8">
      <select id="Importance" name="Importance" class="form-control select2" placeholder="重要级别..."></select>
    </div>
  </div>
</div>
 <div class="col-md-6">
  <div class="form-group">
    <label class="control-label col-md-4">认可程度</label>
    <div class="col-md-8">
      <select id="Recognition" name="Recognition" class="form-control select2" placeholder="认可程度..."></select>
    </div>
  </div>
</div>

万一是一贯列表,那么约等于设置它的Option内容即可,如下所示。

<div class="col-md-6">
  <div class="form-group">
    <label class="control-label col-md-4">吸烟</label>
    <div class="col-md-8">
      <select id="Smoking" name="Smoking" type="text" class="form-control select2" placeholder="吸烟...">
        <option>吸烟</option>
        <option>不吸烟</option>
      </select>
    </div>
  </div>
</div>

大约的select2控件初阶化代码如下所示。

$(document).ready(function() {
 $(".js-example-basic-single").select2();
});

一般情况下,假如同意复选四个类型,那么设置multiple=”multiple”即可,如下代码所示。

<select id="ResponseDemand" name="ResponseDemand" multiple="multiple" class="form-control select2"></select>

2)异步数据绑定操作

貌似景观下,大家的select控件的数量,是从数据Curry面动态加载的,因而一般是由此Ajax格局获取数据并进行绑定即可。

据悉代码可重用性的考虑,大家编辑1个公用的JS函数,用来减弱绑定操作的代码,进步代码重用性。

//绑定字典内容到指定的Select控件
function BindSelect(ctrlName, url) {
  var control = $('#' + ctrlName);
  //设置Select2的处理
  control.select2({
    allowClear: true,
    formatResult: formatResult,
    formatSelection: formatSelection,
    escapeMarkup: function (m) {
      return m;
    }
  });

  //绑定Ajax的内容
  $.getJSON(url, function (data) {
    control.empty();//清空下拉框
    $.each(data, function (i, item) {
      control.append("<option value='" + item.Value + "'> " + item.Text + "</option>");
    });
  });
}

诸如此类,绑定公用字典模块的数额,也就足以经过上面进一步封装处理即可。

//绑定字典内容到指定的控件
function BindDictItem(ctrlName, dictTypeName) {
  var url = '/DictData/GetDictJson?dictTypeName=' + encodeURI(dictTypeName);
  BindSelect(ctrlName, url);
}

诸如此类大家最先化Select2
控件,并动态绑定对应的字典值或然此外数据,则足以通过上面先导化代码即可完结。其中BindDictItem就是一直绑定字典内容的操作,BindSelect则是基于UKugaL举办数据的获取并绑定,而$(“#Province”).on(“change”,
function (e) {});那样的函数处理,就是拍卖采纳内容变更的联动操作了。

 //初始化字典信息(下拉列表)
    function InitDictItem() {
      //部分赋值参考      
      BindDictItem("Area","市场分区");
      BindDictItem("Industry", "客户行业");
      BindDictItem("Grade","客户级别");
      BindDictItem("CustomerType", "客户类型");
      BindDictItem("Source", "客户来源");
      BindDictItem("CreditStatus", "信用等级");
      BindDictItem("Stage","客户阶段");
      BindDictItem("Status", "客户状态");
      BindDictItem("Importance", "重要级别");   
      // 绑定省份、城市、行政区(联动处理)
      BindSelect("Province", "/Province/GetAllProvinceNameDictJson");
      $("#Province").on("change", function (e) {
        var provinceName = $("#Province").val();
        BindSelect("City", "/City/GetCitysByProvinceNameDictJson?provinceName="+ provinceName);
      });
      $("#City").on("change", function (e) {
        var cityName = $("#City").val();
        BindSelect("District", "/District/GetDistrictByCityNameDictJson?cityName="+ cityName);
      });
    }

而其中MVC控制器重临的数据,大家是回来2个JSON数据列表给前端页面的,他们的数目格式如下所示。

[ { "Text": "", "Value": "" }, { "Text": "学术会议", "Value": "学术会议" }, { "Text": "朋友介绍", "Value": "朋友介绍" }, { "Text": "广告媒体", "Value": "广告媒体" } ]

如此那般前端页面绑定Select2控件的时候,就动用了JSON对象的习性即可。

//绑定Ajax的内容
  $.getJSON(url, function (data) {
    control.empty();//清空下拉框
    $.each(data, function (i, item) {
      control.append("<option value='" + item.Value + "'> " + item.Text + "</option>");
    });
  });

控制器的完结代码如下:

 /// <summary>
    /// 根据字典类型获取对应的字典数据,方便UI控件的绑定
    /// </summary>
    /// <param name="dictTypeName">字典类型名称</param>
    /// <returns></returns>
    public ActionResult GetDictJson(string dictTypeName)
    {
      List<CListItem> treeList = new List<CListItem>();
      CListItem pNode = new CListItem("", "");
      treeList.Insert(0, pNode);
      Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName);
      foreach (string key in dict.Keys)
      {
        treeList.Add(new CListItem(key, dict[key]));
      }
      return ToJsonContent(treeList);
    }

3)树形列表的绑定操作

对此属性列表,如所属公司、所属单位部门等有层次性的数目,它的绑定操作也是相近的,如下代码所示。

 //绑定添加界面的公司、部门、直属经理
      BindSelect("Company_ID", "/User/GetMyCompanyDictJson?userId="+@Session["UserId"]);
      $("#Company_ID").on("change", function (e) {
        var companyid = $("#Company_ID").val();
        BindSelect("Dept_ID", "/User/GetDeptDictJson?parentId="+ companyid);
      });
      $("#Dept_ID").on("change", function (e) {
        var deptid = $("#Dept_ID").val();
        BindSelect("PID", "/User/GetUserDictJson?deptId="+ deptid);
      });

只是它们重回的多少,大家把它当做有缩进的显示内容而已。

[ { "Text": "爱奇迪集团", "Value": "1" }, { "Text": " 广州分公司", "Value": "3" }, { "Text": " 上海分公司", "Value": "4" }, { "Text": " 北京分公司", "Value": "5" } ]

如故正如所示

[ { "Text": "广州分公司", "Value": "3" }, { "Text": "总经办", "Value": "6" }, { "Text": "财务部", "Value": "7" }, { "Text": "工程部", "Value": "8" }, { "Text": "产品研发部", "Value": "9" }, { "Text": "  开发一组", "Value": "14" }, { "Text": "  开发二组", "Value": "15" }, { "Text": "  测试组", "Value": "16" }, { "Text": "市场部", "Value": "10" }, { "Text": "  市场一部", "Value": "23" }, { "Text": "  市场二部", "Value": "24" }, { "Text": "综合部", "Value": "11" }, { "Text": "生产部", "Value": "12" }, { "Text": "人力资源部", "Value": "13" } ]

综上八个部分,我们可以看来它们的Text的内容,是依照层次关系展开空格增加,从而已毕了层次关系的显得。

882828九五至尊手机版 12

但是从这几个界面效果上讲,那样的拍卖真的并未EasyUI里面,对下拉列表树的浮现美观,大概可以使用更好的Bootstrap插件进行那些树形内容的显得。

882828九五至尊手机版 13882828九五至尊手机版 14

4)select2控件的赋值处理

地点介绍的章程,都以介绍select2控件的开首化,绑定相关的数码,那么只要开始化界面后,大家绑定编辑界面的值的时候,就需求赋值给控件,让它显得的确须要突显的系列了。

如清空控件的办法如下所示。

//清空Select2控件的值
      $("#PID").select2("val", "");
      $("#Company_ID").select2("val", "");
      $("#Dept_ID").select2("val", "");

比方对于七个控件,须求排除,则可以利用集合举办处理

 var select2Ctrl = ["Area","Industry","Grade","CustomerType","Source","CreditStatus","Stage","Status","Importance"];
      $.each(select2Ctrl, function (i, item) {
        var ctrl = $("#" + item);
        ctrl.select2("val", "");
      });

给Select2
控件赋值,让它显示对应值内容的品类,那么操作也就和方面的好像了。

 $("#CustomerType").select2("val", info.CustomerType);
         $("#Grade").select2("val", info.Grade);
         $("#CreditStatus").select2("val", info.CreditStatus);
         $("#Importance").select2("val", info.Importance);
         $("#IsPublic").select2("val", info.IsPublic);

设若须要级联展现的,那么做法增添2个onchange的函数处理就可以了,如下边联代码的赋值处理如下。

 $("#Province").select2("val", info.Province).trigger('change');//联动
         $("#City").select2("val", info.City).trigger('change');//联动
         $("#District").select2("val", info.District); 
        $("#Company_ID1").select2("val", info.Company_ID).trigger('change');
        $("#Dept_ID1").select2("val", info.Dept_ID).trigger('change');
        $("#PID1").select2("val", info.PID);

终极来多个全体性的界面效果,供参考。

882828九五至尊手机版 15

882828九五至尊手机版 16

882828九五至尊手机版 17

如上所述是小编给大家介绍的根据BootStrap
Metronic开发框架经验计算【三】下拉列表Select2插件的行使的连锁内容,希望对大家具有帮助,假使我们想精通更加多新闻敬请关怀脚本之家网站!

您大概感兴趣的稿子:

Your Comments

近期评论

    功能


    网站地图xml地图