I prefer to use hyperlink-style text by overriding the drawing code and handling mouse move/click events, as buttons don't scale too well to the typical row height of a grid. However, if a button is really what you want, you should be able to do that using the RepositoryItemButtonEdit
as the editor type.
If you're interested in the former, leave a comment and I'll update this with an example. Otherwise, as mentioned, just use the RepositoryItemButtonEdit
. You can change its properties to take up the whole cell if you want, and then make the column a fixed size so the button doesn't get stretched.
UPDATE: I'm posting some sample code for the "pretty hyperlink" below, which I like a lot better than a standard Hyperlink cell because (a) it looks nicer, (b) it gives hover feedback, and (c) you can change the cursor if you want (I use a utility method to get the native hand cursor from the OS, which has a more 3D look than Winforms' built-in hand).
Note to non-DevExpress users reading this: I use almost an identical technique for the standard System.Windows.Forms.ListView
. Microsoft uses this UI pattern quite a bit in Vista and Windows 7 and it's good to learn how to do, even if the result isn't a perfect replica.
private int hoverRowHandle = GridControl.InvalidRowHandle;
private void gridView_Click(object sender, EventArgs e)
{
if (hoverRowHandle != GridControl.InvalidRowHandle)
{
MyItem item = gridView.GetRow(hoverRowHandle) as MyItem;
if (item != null)
// Do whatever the "click" action is here
}
}
private void gridView_CustomDrawCell(object sender,
RowCellCustomDrawEventArgs e)
{
if (e.Column == linkColumn)
{
bool hover = (hoverRowHandle == e.RowHandle);
FontStyle style = hover ? FontStyle.Underline : FontStyle.Regular;
TextFormatFlags formatFlags =
TextFormatFlags.Left | TextFormatFlags.VerticalCenter |
TextFormatFlags.WordEllipsis;
Color foreColor = gridView.IsRowSelected(e.RowHandle) ?
Color.White : (hover ? MyColors.LinkHover : MyColors.Link);
using (Font font = new Font(gridControl.Font, style))
{
TextRenderer.DrawText(e.Graphics, "Link Text", font, e.Bounds,
foreColor, formatFlags);
}
e.Handled = true;
}
}
private void gridView_MouseLeave(object sender, EventArgs e)
{
int tempRowHandle = hoverRowHandle;
hoverRowHandle = GridControl.InvalidRowHandle;
if (tempRowHandle != GridControl.InvalidRowHandle)
{
gridView.InvalidateRowCell(tempRowHandle, linkColumn);
}
}
private void gridView_MouseMove(object sender, MouseEventArgs e)
{
int tempRowHandle = hoverRowHandle;
if (tempRowHandle != GridControl.InvalidRowHandle)
{
hoverRowHandle = GridControl.InvalidRowHandle;
gridView.InvalidateRowCell(tempRowHandle, linkColumn);
}
GridHitInfo hitInfo = gridView.CalcHitInfo(e.Location);
if (hitInfo.InRowCell && (hitInfo.Column == linkColumn))
{
hoverRowHandle = hitInfo.RowHandle;
gridView.InvalidateRowCell(hoverRowHandle, linkColumn);
}
bool hoverDetail = (hoverRowHandle != GridControl.InvalidRowHandle);
gridControl.Cursor = hoverDetail ? Cursors.Hand : Cursors.Default;
}
A few notes about this code:
MyItem
is whatever type of data you have bound to the grid view. Maybe it's a DataRow
, or maybe it's some custom type if the data source is an IList<T>
.
MyColors
is a utility class that defines a couple of public static readonly Color
fields used for UI stuff. You can replace the references to that with hard-coded colours if you're only ever going to do this on one grid.
I don't bother caching the Font
, although you probably could, since there are only two of them.
The cursor logic will mess with any other cursor logic you might use in the grid (which is virtually none in almost every case for me, so generally you should be fine).
If you want to have more than one "link column", you need to maintain a hoverColumn
state field in addition to the hoverRowHandle
, and obviously change those single-column equality comparisons to search for multiple columns.
For my own Winforms apps, I actually have an Extender Provider that lets me attach this behaviour to a GridView
or ListView
by tossing in a list of column name/link text pairs, but that code is just a wee bit too long to post here. The example above should get you started.