//===================================================================== /// <summary> /// This is used to clone the column /// </summary> /// <returns>A clone of the column</returns> public override object Clone() { RatingColumn clone = (RatingColumn)base.Clone(); clone.ImageList = images; clone.MaximumRating = maxRating; return(clone); }
/// <summary> /// This is overridden to update the cell value with a new rating value when it is clicked /// </summary> /// <param name="e">The event arguments</param> protected override void OnContentClick(DataGridViewCellEventArgs e) { RatingColumn owner = base.OwningColumn as RatingColumn; int rating; object newValue = this.NewValue; if (keyRating != -1) { rating = keyRating; } else if (this.MouseRating != -1) { rating = this.MouseRating + 1; } else { rating = -1; } if (!base.ReadOnly && base.DataGridView != null && owner != null && rating != -1 && rating <= owner.MaximumRating) { // Let the user map the rating to a cell value MapRatingEventArgs mapArgs = new MapRatingEventArgs(e.ColumnIndex, e.RowIndex, rating, rating); owner.OnMapRatingToValue(mapArgs); // If the value changed, use that. If the value didn't change, use the new index value but // convert it to the matching type. if (mapArgs.Value == null || !mapArgs.Value.Equals(rating)) { this.NewValue = mapArgs.Value; } else if (newValue is int) { this.NewValue = rating; } else if (newValue is short) { this.NewValue = (short)rating; } else { this.NewValue = mapArgs.Value; } base.DataGridView.NotifyCurrentCellDirty(true); base.DataGridView.InvalidateCell(this); } }
/// <summary> /// Change the mouse cursor back to the default when leaving the cell /// </summary> /// <param name="rowIndex">The row index of the cell</param> protected override void OnMouseLeave(int rowIndex) { RatingColumn owner = base.OwningColumn as RatingColumn; if (!base.ReadOnly && owner != null && base.DataGridView.Cursor != owner.OriginalCursor) { base.DataGridView.Cursor = owner.OriginalCursor; } this.MouseRating = -1; base.OnMouseLeave(rowIndex); base.DataGridView.InvalidateCell(base.ColumnIndex, rowIndex); }
/// <summary> /// Gets the image to display in the cell /// </summary> /// <param name="value">The value to be use in determining the image</param> /// <param name="rowIndex">The index of the cell's parent row</param> /// <returns>The image that should be displayed in the cell</returns> protected override object GetCellImage(object value, int rowIndex) { RatingColumn owner = base.OwningColumn as RatingColumn; // If this is a shared cell, we don't want to draw hot images as they may end up in several places. // As such, only draw them if the mouse is in the cell being drawn. Point mouseCell = DataGridViewHelper.MouseEnteredCellAddress(base.DataGridView); if (owner != null) { return(owner.DrawImage(value, rowIndex, (mouseCell.X == owner.Index && mouseCell.Y == rowIndex) ? this.MouseRating : -1)); } return(null); }
/// <summary> /// Change the mouse pointer to a hand when the mouse moves over one of the images /// </summary> /// <param name="e">The event arguments</param> protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) { RatingColumn owner = base.OwningColumn as RatingColumn; Rectangle content = base.GetContentBounds(e.RowIndex); Cursor newCursor = null; int index, width, lastMouseRating = this.MouseRating; base.OnMouseMove(e); this.MouseRating = -1; // Figure out if the mouse is actually over an image if (owner != null && !base.ReadOnly) { newCursor = owner.OriginalCursor; if (content.Contains(e.Location)) { width = owner.ImageListInternal.ImageSize.Width; index = (e.Location.X - content.X) / width; if (e.Location.X - content.X - (index * width) < width) { newCursor = Cursors.Hand; this.MouseRating = index; } } // Update the cursor if necessary and redraw the cell if (base.DataGridView != null) { if (newCursor != null && base.DataGridView.Cursor != newCursor) { base.DataGridView.Cursor = newCursor; } if (this.MouseRating != lastMouseRating) { base.DataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex); } } } }
/// <summary> /// Calculates the preferred size, in pixels, of the cell /// </summary> /// <param name="graphics">The graphics context for the cell</param> /// <param name="cellStyle">The cell style</param> /// <param name="rowIndex">The index of the cell's parent row</param> /// <param name="constraintSize">The cell's maximum allowable size</param> /// <returns>The preferred cell size in pixels</returns> protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) { Size size; int widthOffset, heightOffset, freeDimension; if (base.DataGridView == null || base.OwningColumn == null) { return(new Size(-1, -1)); } if (cellStyle == null) { throw new ArgumentNullException("cellStyle"); } if (constraintSize.Width == 0) { if (constraintSize.Height == 0) { freeDimension = 0; // Both free } else { freeDimension = 2; // Width is free } } else { freeDimension = 1; // Height is free } DataGridViewAdvancedBorderStyle borderStylePlaceholder = new DataGridViewAdvancedBorderStyle(); DataGridViewAdvancedBorderStyle advancedBorderStyle = base.AdjustCellBorderStyle( base.DataGridView.AdvancedCellBorderStyle, borderStylePlaceholder, false, false, false, false); Rectangle borderWidths = base.BorderWidths(advancedBorderStyle); widthOffset = (borderWidths.Left + borderWidths.Width) + cellStyle.Padding.Horizontal; heightOffset = (borderWidths.Top + borderWidths.Height) + cellStyle.Padding.Vertical; RatingColumn owner = base.OwningColumn as RatingColumn; size = new Size(owner.ImageListInternal.ImageSize.Width * owner.MaximumRating, owner.ImageListInternal.ImageSize.Height); switch (freeDimension) { case 1: size.Width = 0; break; case 2: size.Height = 0; break; } if (freeDimension != 1) { size.Width += widthOffset; if (base.DataGridView.ShowCellErrors) { size.Width = Math.Max(size.Width, widthOffset + 16); } } if (freeDimension != 2) { size.Height += heightOffset; if (base.DataGridView.ShowCellErrors) { size.Height = Math.Max(size.Height, heightOffset + 16); } } return(size); }