需要有关过滤DataGrid的意见 [英] Need advice about filtering DataGrid

查看:139
本文介绍了需要有关过滤DataGrid的意见的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用.NET 3.5,C#和WinForms

I'm using .NET 3.5, C#, and WinForms.

我的网格有很多列:SELLERNAME,BUYERNAME,LoadType,LoadName,的DriverName,CarSerialNumber,等我想过滤的BindingSource。我没有使用组合框这里面充满上下拉的网格单元的价值观,但它并不实用,使得一个难看的形式。

My grid has lots of columns: SellerName, BuyerName, LoadType, LoadName, DriverName, CarSerialNumber, etc. I want to filter the BindingSource. I did this using ComboBoxes which is filled on DropDown with the grid cells' values, but it's not practical and makes for a bad-looking form.

我需要咨询什么是为了让用户选择网格的值,然后用一个按钮筛选的最佳方式。我可以像在Excel中?有列标题一个按钮,当用户按下它,它示出了具有检查列表框有点菜单。当用户选中的值,并且按下一个按钮,就开始过滤。

I need advice on what is the best way to let the user choose values of the grid and then filter with a button. Can I make it like in Excel? There is a button on the column header, and when the user presses it, it shows a little menu with a checked list box. When the user checks any values and press a button it begins filtering.

请告诉我的东西。

这是Excel的图:

谢谢!

推荐答案

好了,结果
首先应该创建自定义过滤用户控件,如你所愿相似以一个在Excel中。

Well,
first of all you should create your custom filter usercontrol, as similar as you wish to the one in excel.

其次,这是不容易做到,但你可以添加过滤器按钮的网格(简单地做 grid.Controls 。新增(...)),并让他们通过覆盖 OnColumnWidthChanged / OnColumnHeadersHeightChanged 的DataGridView的<与列的标题对齐/ code>。

Secondly, it's not easy to do, but you could add filter buttons to the grid (simply doing grid.Controls.Add(...)) and keep them aligned with columns' headers by overriding OnColumnWidthChanged/OnColumnHeadersHeightChanged of DatagridView.

最后,当用户点击过滤器按钮,就可以打开 ToolStripDropDown 与您的自定义过滤器嵌在里面,我的意思是(与你的控制,而不是在ListView明显)类似这样的回答了一句:结果
下拉菜单在滚动条在.NET

Finally, when user clicks on filter button, you can open a ToolStripDropDown with your custom filter embedded in it, I mean something similar to this answer (obviously with your control instead of the listview):
DropDown Menu with ScrollBar in .NET

编辑:

下面是一个(工作)的代码示例:

Here's a (working) code sample:

自定义列标题单元格类别:

public class DataGridFilterHeader : DataGridViewColumnHeaderCell
{
    PushButtonState currentState = PushButtonState.Normal;
    Point cellLocation;
    Rectangle buttonRect;

    public event EventHandler<ColumnFilterClickedEventArg> FilterButtonClicked;

    protected override void Paint(Graphics graphics,
                                  Rectangle clipBounds,
                                  Rectangle cellBounds,
                                  int rowIndex,
                                  DataGridViewElementStates dataGridViewElementState,
                                  object value,
                                  object formattedValue,
                                  string errorText,
                                  DataGridViewCellStyle cellStyle,
                                  DataGridViewAdvancedBorderStyle advancedBorderStyle,
                                  DataGridViewPaintParts paintParts)
    {
        base.Paint(graphics, clipBounds,
                   cellBounds, rowIndex,
                   dataGridViewElementState, value,
                   formattedValue, errorText,
                   cellStyle, advancedBorderStyle, paintParts);

        int width = 20; // 20 px
        buttonRect = new Rectangle(cellBounds.X + cellBounds.Width - width, cellBounds.Y, width, cellBounds.Height);

        cellLocation = cellBounds.Location;
        // to set image/ or some other properties to the filter button look at DrawButton overloads
        ButtonRenderer.DrawButton(graphics,
                                  buttonRect,
                                  "F",
                                  this.DataGridView.Font,
                                  false,
                                  currentState);
    }

    protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
    {
        if (this.IsMouseOverButton(e.Location))
            currentState = PushButtonState.Pressed;
        base.OnMouseDown(e);
    }
    protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
    {
        if (this.IsMouseOverButton(e.Location))
        {
            currentState = PushButtonState.Normal;
            this.OnFilterButtonClicked();
        }
        base.OnMouseUp(e);
    }
    private bool IsMouseOverButton(Point e)
    {
        Point p = new Point(e.X + cellLocation.X, e.Y + cellLocation.Y);
        if (p.X >= buttonRect.X && p.X <= buttonRect.X + buttonRect.Width &&
            p.Y >= buttonRect.Y && p.Y <= buttonRect.Y + buttonRect.Height)
        {
            return true;
        }
        return false;
    }
    protected virtual void OnFilterButtonClicked()
    {
        if (this.FilterButtonClicked != null)
            this.FilterButtonClicked(this, new ColumnFilterClickedEventArg(this.ColumnIndex, this.buttonRect));
    }
}

自定义事件参数:

public class ColumnFilterClickedEventArg : EventArgs
{
    public int ColumnIndex { get; private set; }
    public Rectangle ButtonRectangle { get; private set; }
    public ColumnFilterClickedEventArg(int colIndex, Rectangle btnRect)
    {
        this.ColumnIndex = colIndex;
        this.ButtonRectangle = btnRect;
    }
}



的DataGridView覆盖:

public class DataGridWithFilter : DataGridView
{
    protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
    {
        var header = new DataGridFilterHeader();
        header.FilterButtonClicked += new EventHandler<ColumnFilterClickedEventArg>(header_FilterButtonClicked);
        e.Column.HeaderCell = header;
        base.OnColumnAdded(e);
    }

    void header_FilterButtonClicked(object sender, ColumnFilterClickedEventArg e)
    {
        // open a popup on the bottom-left corner of the
        // filter button
        // here's we add a simple hello world textbox, but you should add your filter control
        TextBox innerCtrl = new TextBox();
        innerCtrl.Text = "Hello World !";
        innerCtrl.Size = new System.Drawing.Size(100, 30);

        var popup = new ToolStripDropDown();
        popup.AutoSize = false;
        popup.Margin = Padding.Empty;
        popup.Padding = Padding.Empty;
        ToolStripControlHost host = new ToolStripControlHost(innerCtrl);
        host.Margin = Padding.Empty;
        host.Padding = Padding.Empty;
        host.AutoSize = false;
        host.Size = innerCtrl.Size;
        popup.Size = innerCtrl.Size;
        popup.Items.Add(host);

        // show the popup
        popup.Show(this, e.ButtonRectangle.X, e.ButtonRectangle.Bottom);
    }
}



结果:

编辑2:

下面是一个完整的VS2008工程样品(DataGrid中使用自定义过滤器,而不是仅仅的Hello World): - > http://www.mediafire.com/? s6o8jmpzh0t82v2

Here's a full VS2008 project sample (DataGrid with customized filter, not just "Hello World"): --> http://www.mediafire.com/?s6o8jmpzh0t82v2

这篇关于需要有关过滤DataGrid的意见的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆