利用devexpress的gridLookUpEdit制作多选下拉框带过滤

先上效果图

在这里插入图片描述

1, 先写一个 GridCheckMarksSelection 类

    class GridCheckMarksSelection
    {
        #region Fileds
        RepositoryItemGridLookUpEdit _currentRepository;

        protected ArrayList selection;
        protected String checkColumnFieldName = "CheckMarkSelection";
        RepositoryItemCheckEdit edit;
        const Int32 CheckboxIndent = 4;
        #endregion

        #region Construct
        public GridCheckMarksSelection(RepositoryItemGridLookUpEdit repository)
            : this()
        {
            CurrentRepository = repository;
        }

        public RepositoryItemGridLookUpEdit CurrentRepository
        {
            get { return _currentRepository; }
            set
            {
                if (_currentRepository != value)
                {
                    Detach();
                    Attach(value);
                }
            }
        }

        public GridCheckMarksSelection()
        {
            selection = new ArrayList();
            this.OnSelectionChanged();
        }
        #endregion

        #region Attribute
        public ArrayList Selection
        {
            get { return selection; }
            set { selection = value; }
        }

        public Int32 SelectedCount { get { return selection.Count; } }
        #endregion

        #region GridSelect
        public object GetSelectedRow(Int32 index)
        { return selection[index]; }

        public Int32 GetSelectedIndex(object row)
        { return selection.IndexOf(row); }

        public void ClearSelection(GridView currentView)
        {
            selection.Clear();
            Invalidate(currentView);
            OnSelectionChanged();
        }

        public void SelectAll(object sourceObject)
        {
            selection.Clear();
            if (sourceObject != null)
            {
                if (sourceObject is ICollection)
                    selection.AddRange(((ICollection)sourceObject));
                else
                {
                    GridView currentView = sourceObject as GridView;
                    for (Int32 i = 0; i < currentView.DataRowCount; i++)
                        selection.Add(currentView.GetRow(i));
                    Invalidate(currentView);
                }
            }
            this.OnSelectionChanged();
        }

        public delegate void SelectionChangedEventHandler(object sender, EventArgs e);
        public event SelectionChangedEventHandler SelectionChanged;
        public void OnSelectionChanged()
        {
            if (SelectionChanged != null)
            {
                EventArgs e = new EventArgs();
                SelectionChanged(this, e);
            }
        }
        public void SelectGroup(GridView currentView, Int32 rowHandle, bool select)
        {
            if (IsGroupRowSelected(currentView, rowHandle) && select) return;
            for (Int32 i = 0; i < currentView.GetChildRowCount(rowHandle); i++)
            {
                Int32 childRowHandle = currentView.GetChildRowHandle(rowHandle, i);
                if (currentView.IsGroupRow(childRowHandle))
                    SelectGroup(currentView, childRowHandle, select);
                else
                    SelectRow(currentView, childRowHandle, select, false);
            }
            Invalidate(currentView);
        }

        public void SelectRow(GridView currentView, Int32 rowHandle, bool select)
        {
            SelectRow(currentView, rowHandle, select, true);
        }

        public void InvertRowSelection(GridView currentView, Int32 rowHandle)
        {
            if (currentView.IsDataRow(rowHandle))
                SelectRow(currentView, rowHandle, !IsRowSelected(currentView, rowHandle));
            if (currentView.IsGroupRow(rowHandle))
                SelectGroup(currentView, rowHandle, !IsGroupRowSelected(currentView, rowHandle));
        }

        public bool IsGroupRowSelected(GridView currentView, Int32 rowHandle)
        {
            for (Int32 i = 0; i < currentView.GetChildRowCount(rowHandle); i++)
            {
                Int32 row = currentView.GetChildRowHandle(rowHandle, i);
                if (currentView.IsGroupRow(row))
                {
                    if (!IsGroupRowSelected(currentView, row)) return false;
                }
                else
                    if (!IsRowSelected(currentView, row)) return false;
            }
            return true;
        }

        public bool IsRowSelected(GridView currentView, Int32 rowHandle)
        {
            if (currentView.IsGroupRow(rowHandle))
                return IsGroupRowSelected(currentView, rowHandle);

            object row = currentView.GetRow(rowHandle);
            return GetSelectedIndex(row) != -1;
        }
        #endregion

        #region Attach|Detach
        protected virtual void Attach(RepositoryItemGridLookUpEdit rep)
        {
            if (rep == null) return;
            selection.Clear();
            _currentRepository = rep;

            edit = _currentRepository.View.GridControl.RepositoryItems.Add("CheckEdit") as RepositoryItemCheckEdit;

            GridColumn column = _currentRepository.View.Columns.Add();
            column.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False;
            column.Visible = true;
            column.VisibleIndex = 0;
            column.FieldName = checkColumnFieldName;
            column.Caption = "Mark";
            column.OptionsColumn.ShowCaption = false;
            column.OptionsColumn.AllowEdit = false;
            column.OptionsColumn.AllowSize = false;
            column.UnboundType = DevExpress.Data.UnboundColumnType.Boolean;
            column.Width = GetCheckBoxWidth();
            column.ColumnEdit = edit;

            _currentRepository.View.Click += new EventHandler(View_Click);
            _currentRepository.View.CustomDrawColumnHeader += new ColumnHeaderCustomDrawEventHandler(View_CustomDrawColumnHeader);
            _currentRepository.View.CustomDrawGroupRow += new RowObjectCustomDrawEventHandler(View_CustomDrawGroupRow);
            _currentRepository.View.CustomUnboundColumnData += new CustomColumnDataEventHandler(view_CustomUnboundColumnData);
            _currentRepository.View.KeyDown += new KeyEventHandler(view_KeyDown);
        }

        protected virtual void Detach()
        {
            if (_currentRepository == null) return;
            if (edit != null)
            {
                _currentRepository.View.GridControl.RepositoryItems.Remove(edit);
                edit.Dispose();
            }
            _currentRepository.View.Click -= new EventHandler(View_Click);
            _currentRepository.View.CustomDrawColumnHeader -= new ColumnHeaderCustomDrawEventHandler(View_CustomDrawColumnHeader);
            _currentRepository.View.CustomDrawGroupRow -= new RowObjectCustomDrawEventHandler(View_CustomDrawGroupRow);
            _currentRepository.View.CustomUnboundColumnData -= new CustomColumnDataEventHandler(view_CustomUnboundColumnData);
            _currentRepository.View.KeyDown -= new KeyEventHandler(view_KeyDown);
            _currentRepository = null;
        }

        void Invalidate(GridView currentView)
        {
            currentView.BeginUpdate();
            currentView.EndUpdate();
        }
        void SelectRow(GridView currentView, Int32 rowHandle, bool select, bool invalidate)
        {
            if (IsRowSelected(currentView, rowHandle) == select) return;
            object row = currentView.GetRow(rowHandle);
            if (select)
                selection.Add(row);
            else
                selection.Remove(row);
            if (invalidate)
                Invalidate(currentView);
            OnSelectionChanged();
        }
        void view_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
        {
            GridView currentView = sender as GridView;
            if (e.Column != null && e.Column.FieldName == checkColumnFieldName)
            {
                if (e.IsGetData)
                    e.Value = IsRowSelected(currentView, currentView.GetRowHandle(e.ListSourceRowIndex));
                else
                    SelectRow(currentView, currentView.GetRowHandle(e.ListSourceRowIndex), (bool)e.Value);
            }
        }
        void view_KeyDown(object sender, KeyEventArgs e)
        {
            GridView currentView = sender as GridView;
            if (currentView.FocusedColumn.FieldName != checkColumnFieldName || e.KeyCode != Keys.Space) return;
            InvertRowSelection(currentView, currentView.FocusedRowHandle);
        }
        void View_Click(object sender, EventArgs e)
        {
            GridHitInfo info;
            GridView currentView = (sender as GridView);
            Point pt = currentView.GridControl.PointToClient(Control.MousePosition);
            info = currentView.CalcHitInfo(pt);
            if (info.Column != null && info.Column.FieldName == checkColumnFieldName)
            {
                if (info.InColumn)
                {
                    if (SelectedCount == currentView.DataRowCount)
                        ClearSelection(currentView);
                    else
                        SelectAll(currentView);
                }
                if (info.InRowCell)
                    InvertRowSelection(currentView, info.RowHandle);
            }
            if (info.InRow && currentView.IsGroupRow(info.RowHandle) && info.HitTest != GridHitTest.RowGroupButton)
                InvertRowSelection(currentView, info.RowHandle);
        }
        void View_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
        {
            if (e.Column != null && e.Column.FieldName == checkColumnFieldName)
            {
                e.Info.InnerElements.Clear();
                e.Painter.DrawObject(e.Info);
                DrawCheckBox(e.Graphics, e.Bounds, SelectedCount == (sender as GridView).DataRowCount);
                e.Handled = true;
            }
        }
        void View_CustomDrawGroupRow(object sender, RowObjectCustomDrawEventArgs e)
        {
            DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo info;
            info = e.Info as DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo;

            info.GroupText = "         " + info.GroupText.TrimStart();
            e.Info.Paint.FillRectangle(e.Graphics, e.Appearance.GetBackBrush(e.Cache), e.Bounds);
            e.Painter.DrawObject(e.Info);

            Rectangle r = info.ButtonBounds;
            r.Offset(r.Width + CheckboxIndent * 2 - 1, 0);
            DrawCheckBox(e.Graphics, r, IsGroupRowSelected((sender as GridView), e.RowHandle));
            e.Handled = true;
        }
        #endregion

        #region CheckBox
        protected Int32 GetCheckBoxWidth()
        {
            DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo info = edit.CreateViewInfo() as DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo;
            Int32 width = 0;
            GraphicsInfo.Default.AddGraphics(null);
            try
            {
                width = info.CalcBestFit(GraphicsInfo.Default.Graphics).Width;
            }
            finally
            {
                GraphicsInfo.Default.ReleaseGraphics();
            }
            return width + CheckboxIndent * 2;
        }

        protected void DrawCheckBox(Graphics g, Rectangle r, bool Checked)
        {
            DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo info;
            DevExpress.XtraEditors.Drawing.CheckEditPainter painter;
            DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs args;
            info = edit.CreateViewInfo() as DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo;
            painter = edit.CreatePainter() as DevExpress.XtraEditors.Drawing.CheckEditPainter;
            info.EditValue = Checked;
            info.Bounds = r;
            info.CalcViewInfo(g);
            args = new DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs(info, new DevExpress.Utils.Drawing.GraphicsCache(g), r);
            painter.Draw(args);
            args.Cache.Dispose();
        }
        #endregion
    }

2, 按如下方式使用

        public FormMain()
        {
            InitializeComponent();
            gridLookUpEdit1.Properties.DataSource = dtDepartment; //赋值一个DataTable
            gridLookUpEdit1.Properties.ValueMember = "Id";
            gridLookUpEdit1.Properties.DisplayMember = "Name";
            gridLookUpEdit1.Properties.View.OptionsSelection.MultiSelect = true;
            gridLookUpEdit1.CustomDisplayText += new DevExpress.XtraEditors.Controls.CustomDisplayTextEventHandler(gridLookUpDevice_CustomDisplayText);

            GridCheckMarksSelection gridCheckMarks;
            gridCheckMarks = new GridCheckMarksSelection(gridLookUpEdit1.Properties);
            gridCheckMarks.SelectionChanged += new GridCheckMarksSelection.SelectionChangedEventHandler(gridCheckMarksDevice_SelectionChanged);
            gridLookUpEdit1.Properties.Tag = gridCheckMarks;
        }

        private void gridCheckMarksDevice_SelectionChanged(object sender, EventArgs e)
        {
            if (ActiveControl is GridLookUpEdit)
            {
                StringBuilder sb = new StringBuilder();
                foreach (DataRowView rv in (sender as GridCheckMarksSelection).Selection)
                {
                    if (sb.ToString().Length > 0) { sb.Append(", "); }
                    sb.Append(rv["Name"].ToString());
                }
                (ActiveControl as GridLookUpEdit).Text = sb.ToString();
            }
        }

        // 选中时更新显示的文本1
        private void gridLookUpDevice_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            GridCheckMarksSelection gridCheckMark = sender is GridLookUpEdit ? (sender as GridLookUpEdit).Properties.Tag as GridCheckMarksSelection : (sender as RepositoryItemGridLookUpEdit).Tag as GridCheckMarksSelection;
            if (gridCheckMark == null) return;
            foreach (DataRowView rv in gridCheckMark.Selection)
            {
                if (sb.ToString().Length > 0) { sb.Append(", "); }
                sb.Append(rv["Name"].ToString());
            }
            e.DisplayText = sb.ToString();
            m_sender = sender;
        }

        // 选中时更新显示的文本1
        private List<String> SelectAllDeviceCode(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
        {
            List<String> strDeviceCodeList = new List<String>();

            GridCheckMarksSelection gridCheckMark = sender is GridLookUpEdit ? (sender as GridLookUpEdit).Properties.Tag as GridCheckMarksSelection : (sender as RepositoryItemGridLookUpEdit).Tag as GridCheckMarksSelection;
            if (gridCheckMark == null) return null;
            foreach (DataRowView rv in gridCheckMark.Selection)
            {
                String deviceCode = rv["Code"].ToString();
                strDeviceCodeList.Add(deviceCode);
            }
            return strDeviceCodeList;
        }

        object m_sender;

        //获取选中的值
        public DataTable GetSelectValues()
        {
            if (null == dtDepartment)
            {
                return null;
            }
            DataTable dt = dtDepartment.Clone(); //复制表结构
            if (m_sender != null)
            {
                GridCheckMarksSelection gridCheckMark = m_sender is GridLookUpEdit ? (m_sender as GridLookUpEdit).Properties.Tag as GridCheckMarksSelection : (m_sender as RepositoryItemGridLookUpEdit).Tag as GridCheckMarksSelection;
                if (gridCheckMark != null)
                {
                    foreach (DataRowView rowView in gridCheckMark.Selection)
                    {
                        dt.Rows.Add( rowView.Row.ItemArray);
                    }
                }
            }
            return dt;
        }


        private void button1_Click(object sender, EventArgs e)
        {
            GetSelectValues();
        }

自定义组件

按上面那样使用太复杂了, 我们把这个组件封装一下方便使用
效果图:
在这里插入图片描述

代码:

   // 多选下拉框, 数据源只支持DataTable , 默认字段Id,Name
    public partial class MkSelectMulti : UserControl
    {
        public string Label
        {
            get { return labelControl1.Text; }
            set { labelControl1.Text = value; }
        }

        public string ValueMember
        {
            get { return gridLookUpEdit1.Properties.ValueMember; }
            set { gridLookUpEdit1.Properties.ValueMember = value; }
        }

        public string DisplayMember
        {
            get { return gridLookUpEdit1.Properties.DisplayMember; }
            set { gridLookUpEdit1.Properties.DisplayMember = value; }
        }

        public DataTable DataSource
        {
            get { return (DataTable)gridLookUpEdit1.Properties.DataSource; }
            set
            {
                if (null == value)
                {
                    return;
                }
                gridLookUpEdit1.Properties.DataSource = value;
                gridLookUpEdit1.Properties.ValueMember = string.IsNullOrEmpty(ValueMember) ? "Id": ValueMember;
                gridLookUpEdit1.Properties.DisplayMember = string.IsNullOrEmpty(DisplayMember) ? "Name" : DisplayMember;
                gridLookUpEdit1.Properties.View.OptionsSelection.MultiSelect = true;

                GridCheckMarksSelection gridCheckMarks = new GridCheckMarksSelection(gridLookUpEdit1.Properties);
                gridCheckMarks.SelectionChanged += new GridCheckMarksSelection.SelectionChangedEventHandler(gridCheckMarks_SelectionChanged);
                gridLookUpEdit1.Properties.Tag = gridCheckMarks;
                gridLookUpEdit1.CustomDisplayText += new DevExpress.XtraEditors.Controls.CustomDisplayTextEventHandler(gridLookUpDevice_CustomDisplayText);
            }
        }

        public DataTable Values
        {
            get
            {
                if (null == DataSource)
                {
                    return null;
                }
                DataTable dt = DataSource.Clone(); //复制表结构
                if (m_sender != null)
                {
                    GridCheckMarksSelection gridCheckMark = m_sender is GridLookUpEdit ? (m_sender as GridLookUpEdit).Properties.Tag as GridCheckMarksSelection : (m_sender as RepositoryItemGridLookUpEdit).Tag as GridCheckMarksSelection;
                    if (gridCheckMark != null)
                    {
                        foreach (DataRowView rowView in gridCheckMark.Selection)
                        {
                            dt.Rows.Add(rowView.Row.ItemArray);
                        }
                    }
                }
                return dt;
            }
        }

        private object m_sender;

        public MkSelectMulti()
        {
            InitializeComponent();
            //gridLookUpEdit 实现列过滤
            gridLookUpEdit1.Properties.View.OptionsView.ShowAutoFilterRow = true;
        }

        // 选中时更新显示的文本1
        private void gridCheckMarks_SelectionChanged(object sender, EventArgs e)
        {
            if (ActiveControl is GridLookUpEdit)
            {
                StringBuilder sb = new StringBuilder();
                foreach (DataRowView rv in (sender as GridCheckMarksSelection).Selection)
                {
                    if (sb.ToString().Length > 0) { sb.Append(", "); }
                    sb.Append(rv[DisplayMember].ToString());
                }
                (ActiveControl as GridLookUpEdit).Text = sb.ToString();
            }
        }

        // 选中时更新显示的文本2
        private void gridLookUpDevice_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            GridCheckMarksSelection gridCheckMark = sender is GridLookUpEdit ? (sender as GridLookUpEdit).Properties.Tag as GridCheckMarksSelection : (sender as RepositoryItemGridLookUpEdit).Tag as GridCheckMarksSelection;
            if (gridCheckMark == null) return;
            foreach (DataRowView rv in gridCheckMark.Selection)
            {
                if (sb.ToString().Length > 0) { sb.Append(", "); }
                sb.Append(rv[DisplayMember].ToString());
            }
            e.DisplayText = sb.ToString();
            m_sender = sender;
        }

    }
要实现DevExpress TreeListLookupEdit多选功能,可以按照以下步骤进行操作: 1. 设置TreeListLookupEdit的Properties.TextEditStyle属性为HideText,这样就可以隐藏下拉列表中的文本框,只显示树状结构列表。 2. 为TreeListLookupEdit的TreeList控件添加一个复选框列,可以使用以下代码: ```csharp treeList1.Columns.Add(new TreeListColumn() { Caption = "Selected", Visible = true, Width = 50, FieldName = "Selected", UnboundType = UnboundColumnType.Boolean, OptionsColumn = { AllowEdit = true, ShowCaption = false, ShowInCustomizationForm = false }, ColumnEdit = new RepositoryItemCheckEdit() }); ``` 3. 在TreeListLookupEditEditValueChanged事件中,遍历TreeList中所有节点,如果节点的复选框被选中,则将其对应的数据添加到一个List中,最后将List中的数据合并为一个字符串,可以使用以下代码: ```csharp private void treeListLookupEdit1_EditValueChanged(object sender, EventArgs e) { List<string> selectedValues = new List<string>(); foreach (TreeListNode node in treeListLookupEdit1TreeList.Nodes) { if ((bool)node.GetValue("Selected")) { selectedValues.Add(node.GetValue("Value").ToString()); } AddSelectedNodes(node, selectedValues); } textEdit1.Text = string.Join(",", selectedValues); } private void AddSelectedNodes(TreeListNode node, List<string> selectedValues) { foreach (TreeListNode childNode in node.Nodes) { if ((bool)childNode.GetValue("Selected")) { selectedValues.Add(childNode.GetValue("Value").ToString()); } AddSelectedNodes(childNode, selectedValues); } } ``` 通过以上步骤,就可以实现DevExpress TreeListLookupEdit多选功能。用户可以通过勾选复选框来选择多个节点,选择的节点对应的数据将会以逗号分隔的字符串形式显示在另一个TextEdit控件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值