Back to Devexpress

How To: Custom Draw a Gauge Control

windowsforms-18264-controls-and-libraries-gauges-examples-how-to-custom-draw-a-gauge-control.md

latest8.0 KB
Original Source

How To: Custom Draw a Gauge Control

  • Nov 13, 2018
  • 3 minutes to read

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.

View Example

csharp
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);
        }
    }

}
vb
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