zoukankan      html  css  js  c++  java
  • 玩转控件:封装Dev的SearchLookupEdit

    鸣谢

            随着前面几个章节对控件封装与扩展的分享,不少小伙伴儿们在作者公众号上反馈,并联系作者,表示通过这些系列和源码能学到不少细节上的东西,并运用到了自己的实际项目当中,也有不少伙伴儿反馈更好更优的处理方式。作者在此感谢大家的陪伴与探讨,希望能与大家一起学习,一起进步。

    工欲善其事必先利其器

            公众号反馈最多的是《玩转控件:封装Dev的LabelControl和TextEdit》,表示运用到自己实际项目后,确实大大减少了自己的工作量,并希望能有更多这种类型的博文。为了满足小伙伴儿的心愿,作者后续会分享更多自己实际项目运用到的小技巧,希望能对更多小伙伴儿有更多的帮助和启发。最后,也希望小伙伴儿们能从作者分享对不同类型控件的封装中举一反三,扩展满足自己实际业务的插件。有好的想法,别忘记分享给作者哦,三人行,必有我师嘛~

    Talk is Cheap

              废话不多说,今天作者要分享的也是作者实际项目中遇到的问题——有数据源的下拉搜索框。不少大的企业反馈,公司职员比较多,数据量比较大,鼠标下拉寻找太过繁琐和耗时,能不能提供个更优的处理方式。经过作者一番思索,以迅雷不及掩耳盗铃响叮当之势就找到了符合客户的处理方式——就是Dev的SearchLookupEdit。

              大家也可以直接用Dev的SearchLookupEdit控件,效果还不错,当然为了方便起见,减少自己的操作量,也可以模仿《玩转控件:封装Dev的LabelControl和TextEdit》一样,自己根据实际情况做个封装,来吧!作者陪大家一起重温下封装的乐趣。


    Show me the Code

       和往常一样,新建一个类用来封装和扩展自己实际要用到的属性和事件:

     public partial class KzxSearchComboboxEdit : KzxBaseControl

            初始化的时候,就可以封装好自己要用到的事件:

    public KzxSearchComboboxEdit()
        {
            InitializeComponent();
    
            this.ValueControl.QueryPopUp += new CancelEventHandler(lookUpEdit_QueryPopUp);
            this.ValueControl.Closed += new ClosedEventHandler(lookUpEdit_Closed);
    
            this.CaptionControl.AutoSizeMode = LabelAutoSizeMode.Vertical;
            this.CaptionControl.SizeChanged += new EventHandler(SetSize);
            this.ValueControl.Enter -= new EventHandler(ValueControl_Enter);
            this.ValueControl.Enter += new EventHandler(ValueControl_Enter);
    
            this._SearchLookUpEditView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
            this._SearchLookUpEditView.Name = "gridLookUpEdit1View";
            this._SearchLookUpEditView.OptionsSelection.EnableAppearanceFocusedCell = false;
            this._SearchLookUpEditView.OptionsView.ShowGroupPanel = false;
            this.ValueControl.Properties.PopupFormSize = new System.Drawing.Size((int)(this.ValueControl.Width * 2), (int)(this.ValueControl.Width * 1.5));
    
            if (this.DesignMode == true)
            {
                this.Size = new Size(284, 21);
            }
        }

            把自己实际需要用到的属性做好封装,举个栗子:

     private int _ItemIndex = -1;
      /// <summary>
      /// 选中项的下标
      /// </summary>
      [Category("自定义"), Description("ItemIndex,选中项的下标"), Browsable(false)]
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
      [McDisplayName("ItemIndex")]
      public int ItemIndex
      {
          get
          {
              return this._ItemIndex;
          }
          protected set
          {
              this._ItemIndex = value;
          }
      }
      
      private DataRow _CurrentItem = null;
      /// <summary>
      /// 选中项的DataRow对象
      /// </summary>
      [Category("自定义"), Description("CurrentItem,选中项的DataRow对象"), Browsable(false)]
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
      [McDisplayName("CurrentItem")]
      public DataRow CurrentItem
      {
          get
          {
              return this._CurrentItem;
          }
          protected set
          {
              this._CurrentItem = value;
          }
      }
      
      
      private DataSet _BillDataSet = new DataSet();
      /// <summary>
      /// 单据的数据源
      /// </summary>
      [Category("自定义"), Description("BillDataSet,单据的数据源"), Browsable(false)]
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
      [McDisplayName("BillDataSet")]
      public DataSet BillDataSet
      {
          get
          {
              return this._BillDataSet;
          }
          set
          {
              this._BillDataSet = value;
          }
      }
      
      /// <summary>
      /// 没有多语言的情况下的默认显示标题
      /// </summary>
      [Category("多语言"), Description("DesigeCaption,没有多语言的情况下的默认显示标题"), Browsable(true)]
      [McDisplayName("DesigeCaption")]
      public override string DesigeCaption
      {
          get
          {
              return this.CaptionControl.Text.Trim();
          }
          set
          {
              this.CaptionControl.Text = value;
          }
      }

            也可以根据自己喜好(当然是符合客户习惯的),画蛇添足:

    private bool _IsNull = true;
      /// <summary>
      /// 可空性
      /// </summary>
      [Category("验证"), Description("IsNull,可空性"), Browsable(true)]
      [McDisplayName("IsNull")]
      public override bool IsNull
      {
          get
          {
              SetBackColor();
              return this._IsNull;
          }
          set
          {
              this._IsNull = value;
              SetBackColor();
          }
      }
      ...
        /// <summary>
        /// 设置背景色
        /// </summary>
        private void SetBackColor()
        {
            if (this.ValueControl.Properties.ReadOnly == true)
            {
                this.ValueControl.BackColor = Color.FromArgb(242, 242, 243);
            }
            else
            {
                if (this._IsNull.Equals(true) == false)
                {
                    this.ValueControl.BackColor = Color.Yellow;
                }
                else
                {
                    this.ValueControl.BackColor = this._TextBackColor;
                }
            }
        }

            当设置控件必填的时候,设置控件的背景色用于区分,具体效果如图:

            封装好控件取值,填充值的方法,以及控件数据源绑定的方法(具体根据自己实际项目应用为准,此处只是举个栗子)

    /// <summary>
    /// 取控件的值
    /// </summary>
    /// <return>Object</return>
    public override object GetValue()
    {
        DataRowView rowview = null;
        BindingSource bs = null;
        object v = null;
    
        v = this.ValueControl.EditValue == null || this.ValueControl.EditValue == DBNull.Value ? string.Empty : this.ValueControl.EditValue.ToString();
        return v;
    }
    
    /// <summary>
    /// 设置控件的值
    /// </summary>
    /// <param name="value">控件的值</param>
    /// <return>int</return>
    public override int SetValue(object value)
    {
        this.ValueControl.EditValue = value == null || value == DBNull.Value ? string.Empty : value;
        return 1;
    }
    
    
    /// <summary>
    /// 设置数据绑定
    /// </summary>
    /// <param name="binding">数据绑定对象</param>
    /// <return>int</return>
    public override int SetDataBinding(object binding)
    {
        this.BindingObject = this.ValueControl.DataBindings.Add("EditValue", binding, this.Field, true, DataSourceUpdateMode.OnValidation, string.Empty, this.FormatString);
        SetColumnDisplayFormat();
        if (binding is BindingSource)
        {
            int maxlength = 0;
            if (((BindingSource)binding).DataSource is DataView)
            {
                if (((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].DataType == typeof(string))
                {
                    maxlength = ((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].MaxLength;
                    if (maxlength >= 0)
                    {
                        this.MaxLength = maxlength;
                    }
                }
            }
            else if (((BindingSource)binding).DataSource is DataTable)
            {
                if (((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].DataType == typeof(string))
                {
                    maxlength = ((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].MaxLength;
                    if (maxlength >= 0)
                    {
                        this.MaxLength = maxlength;
                    }
                }
            }
        }
        return 1;
    }
    
    /// <summary>
    /// 设置下拉框的数据源
    /// </summary>
    /// <param name="binding">下拉框的数据源</param>
    /// <param name="displayMember">显示值字段名</param>
    /// <param name="valueMember">实际值字段名</param>
    /// <returns>int</returns>
    public override int SetSourceTableBinding(object binding, string displayMember, string valueMember)
    {
        this.DisplayMemberPath = displayMember;
        this.SelectedValuePath = valueMember;
        this.ValueControl.Properties.DataSource = binding;
        this._ResourceDataSource = binding;
        return 1;
    }

           完成!为测试效果,在窗体Load事件中造个测试数据,看看效果:

    DataTable dataTable = new DataTable("Student"); 
    dataTable.Columns.Add("编号", typeof(String));
    dataTable.Columns.Add("昵称", typeof(String));
    dataTable.Columns.Add("名称", typeof(String)); 
    dataTable.Rows.Add(new String[] { "1", "James", "张三" });
    dataTable.Rows.Add(new String[] { "2", "Mary", "李四" });
    dataTable.Rows.Add(new String[] { "3", "Jack", "王五" });
    dataTable.Rows.Add(new String[] { "4", "joy", "赵六" });
    dataTable.Rows.Add(new String[] { "5", "jay", "钱七"});
    dataTable.Rows.Add(new String[] { "6", "stephen", "康忠鑫"});
    
    kzxSearchCbbeSupperStar.SetSourceTableBinding(dataTable, "名称", "昵称");

           和原始Dev控件一样,支持筛选功能,妈妈再也不用担心客户反馈因数据量大的问题查找不便了!

    结束语

            由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨。

            最后,感谢您的耐心陪伴!如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

  • 相关阅读:
    document.getElementById("mytxt").style.left=""style.left在IE的FF中注意
    asp.net 用户控件中 使用相对路径的解决方法 图片路径问题(用户控件、图片路径) ,ResolveUrl
    探索 Block (一) (手把手讲解Block 底层实现原理)
    iOS 多线程开发 (概念与API简介)
    iOS 性能小点
    iOS runtime (二)(runtime学习之AutoCoding源码分析)
    探索 NSRunLoop (二)(NSRunLoop 自己动手实现SimpleRunLoop)
    iOS NSNotificationCenter (自己实现一个通知中心XMCNotificationCenter)
    iOS runtime (三)(runtime学习之YYModel源码分析)
    iOS runtime(一)(runtime 分析理解)
  • 原文地址:https://www.cnblogs.com/axing/p/12664139.html
Copyright © 2011-2022 走看看