windowsforms-18264-controls-and-libraries-gauges-examples-how-to-custom-draw-a-gauge-control.md
This example shows how to draw a custom appearance for a circular gauge.
To accomplish this task, the BaseGauge.CustomDrawElement is handled for the ArcScaleComponent, ArcScaleNeedleComponent and ArcScaleBackgroundLayerComponent objects of gauge elements.
Run this application to compare the custom and default gauge appearances. To do this, enable/disable the “Handle CustomDraw event” option.
Note that the gauge control is constantly animated to show the appearance changes more vividly.
using System;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.XtraGauges.Core.Primitive;
using DevExpress.XtraGauges.Core.Model;
namespace XtraGauges_CustomDraw {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
Timer timer;
int animationLockCounter = 0;
bool enableCustomDraw = false;
private void arcScaleBackgroundLayerComponent1_CustomDrawElement(object sender, CustomDrawElementEventArgs e) {
if (enableCustomDraw) {
RectangleF bounds = RectangleF.Inflate(e.Info.BoundBox, -15, -15);
e.Context.Graphics.FillEllipse(Brushes.Black, bounds);
bounds.Inflate(-2, -2);
e.Context.Graphics.SetClip(new RectangleF(bounds.Left + bounds.Width * 0.5f,
bounds.Top, bounds.Width * 0.5f, bounds.Height));
e.Context.Graphics.FillEllipse(Brushes.White, bounds);
e.Context.Graphics.ResetClip();
e.Context.Graphics.FillEllipse(Brushes.White, new RectangleF(bounds.Left +
+bounds.Width * 0.25f, bounds.Top, bounds.Width * 0.5f, bounds.Height * 0.5f));
e.Context.Graphics.FillEllipse(Brushes.Black, new RectangleF(bounds.Left + bounds.Width * 0.25f,
bounds.Top + bounds.Height * 0.5f, bounds.Width * 0.5f, bounds.Height * 0.5f));
e.Handled = true;
}
}
private void arcScaleNeedleComponent1_CustomDrawElement(object sender, CustomDrawElementEventArgs e) {
if (enableCustomDraw) {
e.Context.Graphics.FillEllipse(Brushes.White, new RectangleF(50, 112.5f, 25, 25));
e.Context.Graphics.FillEllipse(Brushes.Black, new RectangleF(175, 112.5f, 25, 25));
e.Handled = true;
}
}
private void arcScaleComponent1_CustomDrawElement(object sender, CustomDrawElementEventArgs e) {
if (enableCustomDraw)
e.Handled = true;
}
private void checkEdit1_CheckStateChanged(object sender, EventArgs e) {
enableCustomDraw = checkEdit1.Checked;
arcScaleBackgroundLayerComponent1.Self.ResetCache(CacheKeys.RenderedImage);
gaugeControl1.Refresh();
}
private void Form1_Load(object sender, EventArgs e) {
timer = new Timer();
timer.Interval = 150;
timer.Tick += new EventHandler(OnTimerTick);
timer.Start();
}
void OnTimerTick(object sender, EventArgs e) {
if (animationLockCounter > 0) return;
animationLockCounter++;
arcScaleComponent1.Value = AnimateScaleValue(arcScaleComponent1, 0.05f);
animationLockCounter--;
}
float AnimateScaleValue(IBaseScale scale, float factor) {
Random random = new Random(DateTime.Now.Millisecond);
float deviation = ((float)random.NextDouble() - scale.Percent);
return (scale.Value + (scale.ScaleLength * factor) * deviation);
}
}
}
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports DevExpress.XtraGauges.Core.Primitive
Imports DevExpress.XtraGauges.Core.Model
Namespace XtraGauges_CustomDraw
Partial Public Class Form1
Inherits Form
Public Sub New()
InitializeComponent()
End Sub
Private timer As Timer
Private animationLockCounter As Integer = 0
Private enableCustomDraw As Boolean = False
Private Sub arcScaleBackgroundLayerComponent1_CustomDrawElement(ByVal sender As Object, ByVal e As CustomDrawElementEventArgs) _
Handles arcScaleBackgroundLayerComponent1.CustomDrawElement
If enableCustomDraw Then
Dim bounds As RectangleF = RectangleF.Inflate(e.Info.BoundBox, -15, -15)
e.Context.Graphics.FillEllipse(Brushes.Black, bounds)
bounds.Inflate(-2, -2)
e.Context.Graphics.SetClip(New RectangleF(bounds.Left + bounds.Width * 0.5F, bounds.Top, _
bounds.Width * 0.5F, bounds.Height))
e.Context.Graphics.FillEllipse(Brushes.White, bounds)
e.Context.Graphics.ResetClip()
e.Context.Graphics.FillEllipse(Brushes.White, New RectangleF(bounds.Left + +bounds.Width * 0.25F, _
bounds.Top, bounds.Width * 0.5F, bounds.Height * 0.5F))
e.Context.Graphics.FillEllipse(Brushes.Black, New RectangleF(bounds.Left + bounds.Width * 0.25F, _
bounds.Top + bounds.Height * 0.5F, bounds.Width * 0.5F, bounds.Height * 0.5F))
e.Handled = True
End If
End Sub
Private Sub arcScaleNeedleComponent1_CustomDrawElement(ByVal sender As Object, ByVal e As CustomDrawElementEventArgs) _
Handles arcScaleNeedleComponent1.CustomDrawElement
If enableCustomDraw Then
e.Context.Graphics.FillEllipse(Brushes.White, New RectangleF(50, 112.5F, 25, 25))
e.Context.Graphics.FillEllipse(Brushes.Black, New RectangleF(175, 112.5F, 25, 25))
e.Handled = True
End If
End Sub
Private Sub arcScaleComponent1_CustomDrawElement(ByVal sender As Object, ByVal e As CustomDrawElementEventArgs) _
Handles arcScaleComponent1.CustomDrawElement
If enableCustomDraw Then
e.Handled = True
End If
End Sub
Private Sub checkEdit1_CheckStateChanged(ByVal sender As Object, ByVal e As EventArgs) _
Handles checkEdit1.CheckStateChanged
enableCustomDraw = checkEdit1.Checked
arcScaleBackgroundLayerComponent1.Self.ResetCache(CacheKeys.RenderedImage)
gaugeControl1.Refresh()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
timer = New Timer()
timer.Interval = 150
AddHandler timer.Tick, AddressOf OnTimerTick
timer.Start()
End Sub
Private Sub OnTimerTick(ByVal sender As Object, ByVal e As EventArgs)
If animationLockCounter > 0 Then
Return
End If
animationLockCounter += 1
arcScaleComponent1.Value = AnimateScaleValue(arcScaleComponent1, 0.05F)
animationLockCounter -= 1
End Sub
Private Function AnimateScaleValue(ByVal scale As IBaseScale, ByVal factor As Single) As Single
Dim random As New Random(DateTime.Now.Millisecond)
Dim deviation As Single = (CSng(random.NextDouble()) - scale.Percent)
Return (scale.Value + (scale.ScaleLength * factor) * deviation)
End Function
End Class
End Namespace