DevExpress XtraGrid强制过滤器显示RepositoryItemCheckedComboBoxEdit列的各个值

时间:2015-08-10 14:49:39

标签: c# winforms devexpress

我添加了一个RepositoryItemCheckedComboBoxEdit列作为编辑器。该列的每一行都可以包含预定义类别列表中的一个或多个条目(我们称之为Category1,Category2和Category3),这些条目是字符串并从数据库中读取。

我的问题是过滤器会列出选项,例如:“Category1; Category2”以及“Category1”或“Category1; Category2; Category3”,具体取决于它在所述列的网格中找到的内容(如果其中之一)这些行选择了所有三个类别,这些类别将被视为单独的过滤器选项,而不是将值分解为其组件。

我希望过滤器只列出单个值,而不是组合,但我无法找到解决方案。我已经尝试使用ShowFilterPopupCheckedListBox事件来操作过滤器内容,但现在过滤已完全停止为该列工作。

这是我的代码:

void gridView_ShowFilterPopupCheckedListBox(object sender, DevExpress.XtraGrid.Views.Grid.FilterPopupCheckedListBoxEventArgs e)
{
    List<CheckedListBoxItem> atomicValues = new List<CheckedListBoxItem>();
    if (e.Column.FieldName != "CategoryCollection") { return; }
    for (int i = 0; i < e.CheckedComboBox.Items.Count; i++)
    {
        CheckedListBoxItem item = e.CheckedComboBox.Items[i];
        string itemValue = (string)(item.Value as FilterItem).Value;
        string[] atomicItemValues = itemValue.Split(';');
        foreach (string atomicValue in atomicItemValues)
        {
            string trimmedAtomicValue = atomicValue.Trim();
            atomicValues.Add(new CheckedListBoxItem(trimmedAtomicValue));
        }
    }

    List<CheckedListBoxItem> distinctAtomicValues = atomicValues.GroupBy(x => x.Value).Select(group => group.First()).OrderBy(x => x.Value).ToList();
    e.CheckedComboBox.Items.Clear();
    foreach (CheckedListBoxItem atomicItem in distinctAtomicValues)
    {
        e.CheckedComboBox.Items.Add(atomicItem);
    }
}

2 个答案:

答案 0 :(得分:0)

据我所知,选中过滤器下拉列表不允许添加自定义项目。

作为替代解决方案,您可以使用自动过滤行来使用就地CheckedComboBoxEdit过滤列:

  • 将GridView.OptionsView.ShowAutoFilterRow属性设置为true。
  • 将就地CheckedComboBoxEdit分配给自动过滤行单元格
  • 按以下方式处理GridView.CustomRowCellEdit事件:

-

private void gridView_CustomRowCellEdit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e) 
{
    if (e.Column.FieldName == "YourField" && e.RowHandle == GridControl.AutoFilterRowHandle)
    {
        e.RepositoryItem = repositoryItemCheckedComboBoxEdit;
    }
}

答案 1 :(得分:0)

GridView中没有内置函数,因此您需要从GridView类创建自定义后代。

  • 您需要应用自定义过滤条件,因为默认GridView正在为已选中过滤器应用equals运算符,但您需要使用contains条件。为此,您需要ApplyCheckedColumnFilter
  • GridView方法
  • 此外,如果要在弹出窗口中显示当前应用的过滤器,则需要更新FilterValues对象的CheckedColumnFilterPopup.RepositoryItemFilterComboBox属性。您可以通过将此对象转换为FilterPopupCheckedListBoxEventArgs.CheckedComboBox来获取此CheckedColumnFilterPopup.RepositoryItemFilterComboBox属性。

这是一个例子:

自定义GridView后代:

public class CustomGridView : GridView
{
    protected override void ApplyCheckedColumnFilter(GridColumn column, object stringValues, List<object> checkedValues)
    {
        if (column.ColumnEdit is RepositoryItemCheckedComboBoxEdit)
        {
            var groupOperator =
                new GroupOperator(
                    GroupOperatorType.Or,
                    from checkedValue in checkedValues
                    where checkedValue != null
                    select
                       new FunctionOperator(
                           FunctionOperatorType.Contains,
                           new OperandProperty(column.FieldName),
                           new OperandValue(checkedValue)));

            ColumnFilterInfo filterInfo;

            switch (groupOperator.Operands.Count)
            {
                case 0:
                    filterInfo = new ColumnFilterInfo();
                    break;
                case 1:
                    filterInfo = new ColumnFilterInfo(groupOperator.Operands[0]);
                    break;
                default:
                    filterInfo = new ColumnFilterInfo(groupOperator);
                    break;
            }

            column.FilterInfo = filterInfo;
        }
        else
            base.ApplyCheckedColumnFilter(column, stringValues, checkedValues);
    }
}

ShowFilterPopupCheckedListBox事件处理程序方法:

private void gridView1_ShowFilterPopupCheckedListBox(object sender, FilterPopupCheckedListBoxEventArgs e)
{
    if (!(e.Column.ColumnEdit is RepositoryItemCheckedComboBoxEdit)) { return; }

    var distinctAtomicValues =
        (from value in
             (from atomicItemValues in
                  from item in e.CheckedComboBox.Items.OfType<CheckedListBoxItem>()
                  let itemValue = (string)(item.Value as FilterItem).Value
                  where itemValue != null
                  select itemValue.Split(';')
              from atomicValue in atomicItemValues
              let trimmedAtomicValue = atomicValue.Trim()
              orderby trimmedAtomicValue
              select trimmedAtomicValue).Distinct()
         select new CheckedListBoxItem(value)).ToList();

    e.CheckedComboBox.Items.Clear();

    foreach (var atomicItem in distinctAtomicValues)
        e.CheckedComboBox.Items.Add(atomicItem);

    string filterString = e.Column.FilterInfo.FilterString;

    if (!string.IsNullOrEmpty(filterString))
    {
        var filterItem = (CheckedColumnFilterPopup.RepositoryItemFilterComboBox)e.CheckedComboBox;

        filterItem.FilterValues =
            string.Join("\n",
                from item in filterItem.Items.OfType<CheckedListBoxItem>()
                let itemValue = (string)item.Value
                where itemValue != null && filterString.Contains("Contains([" + e.Column.FieldName + "], '" + item.Value + "'")
                select itemValue);
    }
}