需要有关过滤DataGrid的意见 [英] Need advice about filtering 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屋!