Anda di halaman 1dari 6

14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

Seven-Segment and Sixteen-Segment Controls for WPF


Yury Yuhno, 14 Feb 2019

User controls which allow displaying symbols using 7 and 16 segments

Download application - 56.3 KB

Introduction
Seven and sixteen segment indicators are controls for Windows WPF applications. Each component is split by some figures (shapes)
with nearly the same form and size. Different combinations of colorized segments allow visualizing digital information such as
temperature, time, different calculations and other characters. There are lot of similar controls or ways to create similar labels for
.NET applications, but without full customization. I have tried to put together as many design configuration possibilities as possible
in a single component.

Background
Mostly, segment controls in this application derive from the one base UserControl named SegmentBase. From it derive such
controls as SevenSegments and SixteenSegments, which are responsible for displaying single character with segments.
There is additional base component SegmentsStackBase deriving from SegmentBase, it contains properties to display
sequence of segment controls. From this control come SevenSegmentsStack, which presents list of SevenSegments
components, and SixteenSegmentsStack, which presents list of SixteenSegments components.

Each segment has a corresponding number. Using these numbers, you can apply properties or make other actions with it. Segment
numbers are assigned according to the enumeration Segments.

https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 1/6
14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

public enum Segments


{
Top= 0,
RightTop = 1,
...
}

Properties of Controls

Segment components have the following dependency properties to configure visual appearance:

FillBrush: gets/sets Brush for not selected segments


SelectedFillBrush: gets/sets Brush for selected segments
PenColor: gets/sets Color of pen border for not selected segments
SelectedPenColor: gets/sets Color of pen border for selected segments
GapWidth: gets/sets gap in pixels between segments
RoundedCorners: shows/hides roundness for corners of segments
TiltAngle: gets/sets tilt angle in degrees relatively of Y-axis
ShowDot: shows/hides additional dot segment
ShowColon: shows/hides additional colon segments
OnDot: activates/deactivates dot segment
OnColon: activates/deactivates colon segment
VertSegDivider: gets/sets proportional width of vertical segments (proportional divider number)
HorizSegDivider: gets/sets proportional height of horizontal segments (proportional divider number)
SelectedSegments: gets/sets a list of selected segments set by user
SegmentsBrush: gets/sets list of different brushes for particular segments
https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 2/6
14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

SevenSegmentsStack and SixteenSegmentsStack have an additional dependency property:

ElementsCount: number of segment elements to show

Using the Code


As it has been written above, there are main user controls SevenSegments and SixteenSegments to create segmented
labels. Segments are PathGeometry shapes drawn in the OnRender function. Each path figure is combined in the single class
GeometryWithSegm. It contains corresponding segment number, drawn segment shape and a Boolean property to mark figure
as selected.

public class GeometryWithSegm


{
public PathGeometry Geometry { get; set; }
public Segments SegmentNumber { get; set; }
public bool IsSelected { get; set; }
}
...

To draw a whole figure of segments, a list of GeometryWithSegm classes List <geometrywithsegm>


GeometryFigures</geometrywithsegm><geometrywithsegm> has been used.

protected override void OnRender(DrawingContext drawingContext)


{

GeometryFigures = new List<GeometryWithSegm>();
GeometryFigures.Add(new GeometryWithSegm(TopSegement(), Segments.Top));

foreach (var entry in GeometryFigures)
{
Pen figurePen = new Pen(new SolidColorBrush
(entry.IsSelected ? SelectedPenColor :PenColor), PenThickness);

drawingContext.DrawGeometry(entry.IsSelected ? SelectedFillBrush : FillBrush,


figurePen, entry.Geometry);
}

}
...

Path geometries contain some geometric shapes, PathFigure. In turn, each PathFigure consists of lines and Bezier curves
connected with each other.

protected PathGeometry TopSegement()


{
TopSegmPoints = GetTopSegmPoints();
Point startPoint = TopSegmPoints[0];
LineSegment line0 = new LineSegment(TopSegmPoints[0], true);
...
// The left Bezier curve for rounded corners
var pointsBezierLeft= new PointCollection
{
TopSegmPoints[1], TopSegmPoints[2], TopSegmPoints[3]
};
...
PathGeometry pathGeometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = startPoint;
pathFigure.IsClosed = true;
pathGeometry.Figures.Add(pathFigure);
pathFigure.Segments.Add(line0);
...
return pathGeometry;
}

Points for each line and Bezier curve are calculated in separate functions.

https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 3/6
14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

protected PointCollection GetTopSegmPoints()


{
PointCollection points = new PointCollection();
var topLeftX = LeftTopSegmPoints[1].X + HorizSegSmallPartW;
...
// three left points, starting from the bottom point
points.Add(new Point(LeftTopSegmPoints[2].X + GapW, HorizSegH + startPointThickness));
points.Add(new Point(LeftTopSegmPoints[1].X +
GapShift(), HorizSegSmallPartH + startPointThickness));
points.Add(new Point(topLeftX, startPointThickness));
...
return points;
}

Some of the shapes coordinates required additional calculation to draw inclination. Simple trigonometric equation has been used
according to an angle: tan(alpha) = a/b.

/// <summary>
/// Returns X-coord by the angle and height
/// </summary>
/// <param name="y">Y-coordinate to calculate height</param>
protected double XByAngle(double y)
{
var h = figureStartPointY - y;
return (TanAngle() * h);
}

/// <summary>
/// Returns tangent of the tilt angle in degrees
/// </summary>
protected double TanAngle()
{
return Math.Tan(TiltAngle * (Math.PI / 180.0));
}

Segments are marked as selected corresponding to the required value in the special function. You can extend this function to apply
not supported values.

protected virtual void ValueSegmentsSelection()


{
int tempValue;
if (int.TryParse(Value, out tempValue))
{
switch (tempValue)
{
case 0:
SelectSegments((int) Segments.LeftTop, (int)Segments.Top,
(int)Segments.RightTop, (int)Segments.RightBottom,
(int)Segments.Bottom, (int)Segments.LeftBottom);
break;

}

For this moment, seven segment controls support only numeric values, sixteen segment controls support numeric values and capital
letters.

Also, there is a possibility to select segments without modifying control’s internal implementation through the use of dependency
property SelectedSegments.

int[] segments =
{
(int) SegmentsControls.Segments.LeftMiddle,
(int) SegmentsControls.Segments.RightBottomDiagonal
};

MySegments.ClearSegments();
MySegments.SelectedSegments = segments.ToList();

To apply different colors for particular segments outside control’s realization, it’s possible to use dependency property
SegmentsBrush.
https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 4/6
14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

Tuple<int, Brush, Color>[] brushes =


{
new Tuple<int, Brush, Color>(
(int)SegmentsControls.Segments.RightTop,
new SolidColorBrush(Colors.Yellow),
Colors.Red),
...
};

MySegments.ClearSegments();
MySegments.SegmentsBrush = brushes.ToList();

Stack of Segment Controls


Creation of stack of segment controls is also based on the base control SegmentBase. SevenSegmentsStack and
SixteenSegmentsStack contain simple ItemsControl with items of segment controls.

<ItemsControl x:Name="SegmentsArray" >


<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<segm:ArrangedPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.ItemTemplate>
<DataTemplate>
<segm:ArrangedPanel >
<segm:SevenSegments Value="{Binding Item}"

ShowDot="{Binding ShowDot}"

OnDot="{Binding OnDot}"

Margin="5,0,0,0"/>
</segm:ArrangedPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

An ItemsControl is bound with required list of items.

private ObservableCollection<CharItem> ValueChars;



ValueChars = GetCharsArray();
SegmentsArray.ItemsSource = ValueChars;

In order to apply dots or colons for these controls, it's required to set true for properties ShowDot or ShowColon and set
proper property Value (for example 1:23.4).

History
14th February, 2019 -- Original version posted

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author


https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 5/6
14/02/2019 Seven-Segment and Sixteen-Segment Controls for WPF - CodeProject

Yury Yuhno I specialize in .Net with C#.


Software Developer MSc in Computer Science, Daugavpils University
Latvia

Comments and Discussions


0 messages have been posted for this article Visit https://www.codeproject.com/Articles/1277331/Seven-Segment-and-
Sixteen-Segment-Controls-for-WPF to post and view comments on this article, or click here to get a print view with messages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile Article Copyright 2019 by Yury Yuhno
Web03 | 2.8.190210.1 | Last Updated 14 Feb 2019 Everything else Copyright © CodeProject, 1999-2019

https://www.codeproject.com/Articles/1277331/Seven-Segment-and-Sixteen-Segment-Controls-for-WPF?display=Print 6/6