Star Rating Control [GDI - C#] 04-11-2013, 04:26 AM
#1
Here's a control I came up with as a simple demo of GDI in C#.
Hover Display:
![[Image: 6NwrQ9n.png]](http://i.imgur.com/6NwrQ9n.png)
Rating Saved:
![[Image: 5G9Fjhi.png]](http://i.imgur.com/5G9Fjhi.png)
Hover Display:
![[Image: 6NwrQ9n.png]](http://i.imgur.com/6NwrQ9n.png)
Rating Saved:
![[Image: 5G9Fjhi.png]](http://i.imgur.com/5G9Fjhi.png)
Code:
// N2Oxide Progress Bar
// Author: ArkPhaze (c) 2013
// Site: HackCommunity.com
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
sealed class StarRating : PictureBox
{
// Constructor for initialization
public StarRating()
{
_pOutlineNorm = new Pen(_normOutlineColor);
_pOutlineFaint = new Pen(_faintOutlineColor);
DoubleBuffered = true;
MaximumSize = MinimumSize = new Size(20 * 5, 20);
}
enum FillState
{
None, // No fill
HoverFilled, // Fill for hover display
PermaFilled // Saved fill state
}
// Determines whether rating was already given
public bool Rated { get; private set; }
public short? Rating { get; private set; }
// Container for stars
private readonly List<FillState> _stars = new List<FillState>(5) { FillState.None, FillState.None, FillState.None, FillState.None, FillState.None };
private readonly List<FillState> _savedStars = new List<FillState>(5) { FillState.None, FillState.None, FillState.None, FillState.None, FillState.None };
readonly GraphicsPath _gp = new GraphicsPath();
private readonly Pen _pOutlineNorm;
private Color _normOutlineColor = Color.FromArgb(175, 0, 0);
public Color NormalOutlineColor
{
get { return _normOutlineColor; }
set
{
_pOutlineNorm.Color = value;
_normOutlineColor = value;
}
}
private readonly Pen _pOutlineFaint;
private Color _faintOutlineColor = Color.FromArgb(150, 0, 0, 0);
public Color FaintOutlineColor
{
get { return _faintOutlineColor; }
set
{
_pOutlineFaint.Color = value;
_faintOutlineColor = value;
}
}
private Color _starFillColor = Color.FromArgb(180, 0, 0);
public Color StarFillColor
{
get { return _starFillColor; }
set { _starFillColor = value; }
}
// Responsible for drawing the control
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
_gp.ClearMarkers();
int numFilled = 0;
for (int i = 0; i < 5; i++)
{
FillState fs = Rated ? _savedStars[i] : _stars[i];
DrawStar(e.Graphics, fs, i);
if (fs != FillState.None) numFilled++;
}
e.Graphics.SetClip(new RectangleF(0, 0, (numFilled * 20) + 1, Height), CombineMode.Replace);
using (LinearGradientBrush lgb = new LinearGradientBrush(DisplayRectangle, _starFillColor, Color.FromArgb(200, _starFillColor), 90f))
{
e.Graphics.FillPath(lgb, _gp);
}
e.Graphics.ResetClip();
}
// Show the hover display
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (!Rated)
{
int upperRating = e.X / 20 + 1;
for (int i = 0; i < 5; i++)
{
if (i < upperRating)
{
_stars[i] = FillState.HoverFilled;
}
else
{
_stars[i] = FillState.None;
}
}
Invalidate();
}
}
// Saves changes to the rating
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (Rated)
{
return;
}
Rated = true;
Rating = 0;
for (int i = 0; i < 5; i++)
{
if (_stars[i] == FillState.HoverFilled)
{
_savedStars[i] = FillState.PermaFilled;
Rating++;
}
else
{
_savedStars[i] = FillState.None;
}
}
Invalidate();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (!Rated)
{
for (int i = 0; i < 5; i++)
{
_stars[i] = FillState.None;
}
Invalidate();
}
}
// Other methods
private void DrawStar(Graphics graphics, FillState fillState, int left)
{
Point[] star = new[] {
new Point((20 * left) + 1 , 6),
new Point((20 * left) + 8 , 6),
new Point((20 * left) + 10 , 0),
new Point((20 * left) + 12 , 6),
new Point((20 * left) + 19 , 6),
new Point((20 * left) + 14 , 10),
new Point((20 * left) + 18 , 18),
new Point((20 * left) + 10 , 13),
new Point((20 * left) + 2 , 18),
new Point((20 * left) + 6 , 10)
};
using (LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(new Point(left, 0), new Size(20, 20)), _starFillColor, Color.FromArgb(200, _starFillColor), 90f))
{
if (fillState != FillState.PermaFilled)
{
graphics.DrawPolygon(_pOutlineFaint, star);
if (fillState == FillState.HoverFilled)
{
lgb.LinearColors = new[] { Color.FromArgb(100, _starFillColor), Color.FromArgb(100, _starFillColor) };
graphics.FillPolygon(lgb, star);
}
}
else
{
graphics.DrawPolygon(_pOutlineNorm, star);
if (fillState == FillState.PermaFilled)
{
graphics.FillPolygon(lgb, star);
}
}
}
}
}
ArkPhaze
"Object oriented way to get rich? Inheritance"
Getting Started: C/C++ | Common Mistakes
[ Assembly / C++ / .NET / Haskell / J Programmer ]
"Object oriented way to get rich? Inheritance"
Getting Started: C/C++ | Common Mistakes
[ Assembly / C++ / .NET / Haskell / J Programmer ]


![[+]](https://sinister.li/images/modern/collapse_collapsed.png)
![[Image: OilyCostlyEwe.gif]](http://fat.gfycat.com/OilyCostlyEwe.gif)