当前位置: 移动技术网 > IT编程>开发语言>.net > WPF实现LED数字效果展示

WPF实现LED数字效果展示

2020年07月28日  | 移动技术网IT编程  | 我要评论

贴代码

public class DigitalMeter : Canvas

    {

        private int numDigits;

 

        static DigitalMeter()

        {

           
DefaultStyleKeyProperty.OverrideMetadata(typeof(DigitalMeter), new FrameworkPropertyMetadata(typeof(DigitalMeter)));

        }

 

        public DigitalMeter()

        {

            UpdateControls();

        }

 

        public static readonly DependencyProperty FormatStringProperty =

            DependencyProperty.Register("FormatString", typeof(string), typeof(DigitalMeter), new PropertyMetadata("000.00", OnLayoutPropertyChanged));

 

        public string FormatString

        {

            get { return (string)GetValue(FormatStringProperty); }

            set { SetValue(FormatStringProperty, value); }

        }

 

        public static readonly DependencyProperty BackColorProperty =

            DependencyProperty.Register("BackColor", typeof(Color), typeof(DigitalMeter), new PropertyMetadata(Color.FromArgb(0, 0, 0, 0), OnColorPropertyChanged));

 

        public Color BackColor

        {

            get { return (Color)GetValue(BackColorProperty); }

            set

            {

                SetValue(BackColorProperty, value);

            }

        }

 

        public static readonly DependencyProperty ForeColorProperty =

            DependencyProperty.Register("ForeColor", typeof(Color), typeof(DigitalMeter), new PropertyMetadata(Color.FromRgb(255, 0, 0), OnColorPropertyChanged));

 

        public Color ForeColor

        {

            get { return (Color)GetValue(ForeColorProperty); }

            set { SetValue(ForeColorProperty, value); }

        }

 

        public static readonly DependencyProperty SignedProperty =

            DependencyProperty.Register("Signed", typeof(bool), typeof(DigitalMeter), new PropertyMetadata(false, OnLayoutPropertyChanged));

 

        public bool Signed

        {

            get { return (bool)GetValue(SignedProperty); }

            set { SetValue(SignedProperty, value); }

        }

 

        public static readonly DependencyProperty ValueProperty =

            DependencyProperty.Register("Value", typeof(double), typeof(DigitalMeter), new PropertyMetadata(default(double), OnValuePropertyChanged));

 

        public double Value

        {

            get { return (double)GetValue(ValueProperty); }

            set { SetValue(ValueProperty, value); }

        }

 

        private static void OnLayoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var meters = d as DigitalMeter;

            if (meters == null)

                return;

            meters.UpdateControls();

        }

 

        private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var meters = d as DigitalMeter;

            if (meters == null || meters.Children.Count < 1)

                return;

            foreach (var child in meters.Children)

            {

                var disp = child as DigitalDisplay;

                if (disp == null)

                    continue;

                disp.BackColor =
meters.BackColor;

                disp.ForeColor =
meters.ForeColor;

            }

        }

 

        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var meters = d as DigitalMeter;

            if (meters == null)

                return;

 

            var str = meters.Value.ToString(meters.FormatString);

            str = str.Replace(".", string.Empty);

            str = str.Replace(",", string.Empty);

 

            var sign = false;

            if (str[0] == '-')

            {

                sign = true;

                str = str.TrimStart(new[] { '-' });

            }

 

            if (str.Length > meters.numDigits)

            {

                foreach (var child in meters.Children)

                {

                    var disp = child as DigitalDisplay;

                    if (disp != null) disp.Value = 'E';

                }

                return;

            }

 

            int idx;

            for (idx = str.Length - 1; idx >= 0; idx--)

            {

                var id = idx;

                if (meters.Signed)

                    id++;

                var disp = meters.Children[id] as DigitalDisplay;

                if (disp != null) disp.Value = Convert.ToInt32(str[idx].ToString(CultureInfo.InvariantCulture));

            }

 

            var s = meters.Children[0] as DigitalDisplay;

            if (s != null && s.Name.Equals("digit_sign", StringComparison.CurrentCulture))

            {

                if (sign)

                    s.Value = '-';

                else

                    s.Value = -1;

            }

        }

 

        /// <summary>

        /// Update the controls of the meter

        /// </summary>

        private void UpdateControls()

        {

            string strFormat = FormatString;

            var count = strFormat.Length;

 

            var seps = new[] { '.', ',' };

            var sepIndex = strFormat.IndexOfAny(seps);

            if (sepIndex > 0)

            {

                count--;

                numDigits = count;

            }

 

            numDigits = count;

 

            Children.Clear();

 

            if (Signed)

            {

                var disp = new DigitalDisplay { Name = "digit_sign", Value = -1, BackColor = BackColor, ForeColor =
ForeColor };

                Children.Add(disp);

            }

 

            for (var idx = 0; idx < count; idx++)

            {

                var disp = new DigitalDisplay { Name = "digit_" + idx, BackColor = BackColor, ForeColor =
ForeColor };

                if (sepIndex - 1 == idx)

                    disp.ShowDot = true;

 

                Children.Add(disp);

            }

 

            RepositionControls();

        }

 

        /// <summary>

        /// Reposition of the digital displaies

        /// </summary>

        private void RepositionControls()

        {

            if (Children.Count <= 0)

                return;

 

            var digitW = RenderSize.Width / Children.Count;

            var signFind = false;

            foreach (var disp in Children)

            {

                var d = disp as DigitalDisplay;

                if (d == null)

                    continue;

 

                var idDigit = 0;

                if (d.Name.Contains("digit_sign"))

                {

                    signFind = true;

                }

                else

                {

                    if (d.Name.Contains("digit_"))

                    {

                        var s = d.Name.Remove(0, 6);

                        idDigit = Convert.ToInt32(s);

 

                        if (signFind)

                            idDigit++;

                    }

                }

 

                d.Width = digitW;

                d.Height = RenderSize.Height;

 

                SetLeft(d, idDigit * (digitW -
0.5));

                SetTop(d, 0);

            }

            OnValuePropertyChanged(this, new DependencyPropertyChangedEventArgs(ValueProperty, 0,
Value));

        }

 

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)

        {

            base.OnRenderSizeChanged(sizeInfo);

            RepositionControls();

        }

    }




    public class DigitalDisplay : FrameworkElement

    {

        #region Constants

 

        public const int WIDTH_PIXEL = 11;

        public const int HEIGHT_PIXELS = 18;

 

        #endregion

 

        #region Constructors

 

        static DigitalDisplay()

        {

           
DefaultStyleKeyProperty.OverrideMetadata(typeof(DigitalDisplay), new FrameworkPropertyMetadata(typeof(DigitalDisplay)));

            CreateSegmetsData();

            CreateDefPointsCoordinates();

            CreateSegmentsValuesList();

        }

 

        #endregion

 

        #region Private Variables

        /// <summary>

        /// Segments data array

        /// </summary>

        private static readonly SegmentDictionary Segments = new SegmentDictionary();

        /// <summary>

        /// Defaults points coordinates

        /// </summary>

        private static readonly PointsList DefPoints = new PointsList();

        /// <summary>

        /// Segments list of a value

        /// </summary>

        private static readonly SegmentsValueDictionary ValuesSegments = new SegmentsValueDictionary();

 

        #endregion

 

        #region Dependency Properties

 

        private static void OnDisplayPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var digital = d as DigitalDisplay;

            if (digital != null)

                digital.InvalidateVisual();

        }

 

        public static readonly DependencyProperty ValueProperty =

            DependencyProperty.Register("Value", typeof(int), typeof(DigitalDisplay), new PropertyMetadata(0, OnDisplayPropertyChanged));

 

        public int Value

        {

            get { return (int)GetValue(ValueProperty); }

            set

            {

                SetValue(ValueProperty, value);

            }

        }

 

        public static readonly DependencyProperty ShowDotProperty =

            DependencyProperty.Register("ShowDot", typeof(bool), typeof(DigitalDisplay), new PropertyMetadata(false, OnDisplayPropertyChanged));

 

        public bool ShowDot

        {

            get { return (bool)GetValue(ShowDotProperty); }

            set { SetValue(ShowDotProperty, value); }

        }

 

        public static readonly DependencyProperty ForeColorProperty =

            DependencyProperty.Register("ForeColor", typeof(Color), typeof(DigitalDisplay), new PropertyMetadata(Color.FromRgb(255, 0, 0), OnDisplayPropertyChanged));

 

        public Color ForeColor

        {

            get { return (Color)GetValue(ForeColorProperty); }

            set { SetValue(ForeColorProperty, value); }

        }

 

        public static readonly DependencyProperty BackColorProperty =

            DependencyProperty.Register("BackColor", typeof(Color), typeof(DigitalDisplay), new PropertyMetadata(Color.FromRgb(0, 0, 0), OnDisplayPropertyChanged));

 

        public Color BackColor

        {

            get { return (Color)GetValue(BackColorProperty); }

            set { SetValue(BackColorProperty, value); }

        }

 

        #endregion

 

        #region Static Methods

 

        /// <summary>

        /// Creation of the default points list of the

        /// all segments

        /// </summary>

        private static void CreateDefPointsCoordinates()

        {

            var pt = new Point(3F, 1F);

            DefPoints.Add(pt);

            pt = new Point(8F, 1F);

            DefPoints.Add(pt);

            pt = new Point(9F, 2F);

            DefPoints.Add(pt);

            pt = new Point(10F, 3F);

            DefPoints.Add(pt);

            pt = new Point(10F, 8F);

            DefPoints.Add(pt);

            pt = new Point(9F, 9F);

            DefPoints.Add(pt);

            pt = new Point(10F, 10F);

            DefPoints.Add(pt);

            pt = new Point(10F, 15F);

            DefPoints.Add(pt);

            pt = new Point(9F, 16F);

            DefPoints.Add(pt);

            pt = new Point(8F, 17F);

            DefPoints.Add(pt);

            pt = new Point(3F, 17F);

            DefPoints.Add(pt);

            pt = new Point(2F, 16F);

            DefPoints.Add(pt);

            pt = new Point(1F, 15F);

            DefPoints.Add(pt);

            pt = new Point(1F, 10F);

            DefPoints.Add(pt);

            pt = new Point(2F, 9F);

            DefPoints.Add(pt);

            pt = new Point(1F, 8F);

            DefPoints.Add(pt);

            pt = new Point(1F, 3F);

            DefPoints.Add(pt);

            pt = new Point(2F, 2F);

            DefPoints.Add(pt);

            pt = new Point(3F, 3F);

            DefPoints.Add(pt);

            pt = new Point(8F, 3F);

            DefPoints.Add(pt);

            pt = new Point(8F, 8F);

            DefPoints.Add(pt);

            pt = new Point(8F, 10F);

            DefPoints.Add(pt);

            pt = new Point(8F, 15F);

            DefPoints.Add(pt);

            pt = new Point(3F, 15F);

            DefPoints.Add(pt);

            pt = new Point(3F, 10F);

            DefPoints.Add(pt);

            pt = new Point(3F, 8F);

            DefPoints.Add(pt);

        }

 

        /// <summary>

        /// Create the dictionary of the

        /// segment coordinates

        /// </summary>

        private static void CreateSegmetsData()

        {

            Segments.Clear();

 

            var s = new Segment();

            s.PointsIndexs[0] = 0;

            s.PointsIndexs[1] = 1;

            s.PointsIndexs[2] = 2;

            s.PointsIndexs[3] = 19;

            s.PointsIndexs[4] = 18;

            s.PointsIndexs[5] = 17;

            Segments.Add('A', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 2;

            s.PointsIndexs[1] = 3;

            s.PointsIndexs[2] = 4;

            s.PointsIndexs[3] = 5;

            s.PointsIndexs[4] = 20;

            s.PointsIndexs[5] = 19;

            Segments.Add('B', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 6;

            s.PointsIndexs[1] = 7;

            s.PointsIndexs[2] = 8;

            s.PointsIndexs[3] = 22;

            s.PointsIndexs[4] = 21;

            s.PointsIndexs[5] = 5;

            Segments.Add('C', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 9;

            s.PointsIndexs[1] = 10;

            s.PointsIndexs[2] = 11;

            s.PointsIndexs[3] = 23;

            s.PointsIndexs[4] = 22;

            s.PointsIndexs[5] = 8;

            Segments.Add('D', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 12;

            s.PointsIndexs[1] = 13;

            s.PointsIndexs[2] = 14;

            s.PointsIndexs[3] = 24;

            s.PointsIndexs[4] = 23;

            s.PointsIndexs[5] = 11;

            Segments.Add('E', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 15;

            s.PointsIndexs[1] = 16;

            s.PointsIndexs[2] = 17;

            s.PointsIndexs[3] = 18;

            s.PointsIndexs[4] = 25;

            s.PointsIndexs[5] = 14;

            Segments.Add('F', s);

 

            s = new Segment();

            s.PointsIndexs[0] = 25;

            s.PointsIndexs[1] = 20;

            s.PointsIndexs[2] = 5;

            s.PointsIndexs[3] = 21;

            s.PointsIndexs[4] = 24;

            s.PointsIndexs[5] = 14;

            Segments.Add('G', s);

        }

 

        /// <summary>

        /// Create the dictionary of the segments

        /// for the number values

        /// </summary>

        private static void CreateSegmentsValuesList()

        {

            var list = new SegmentsList { 'A', 'B', 'C', 'D', 'E', 'F' };

            ValuesSegments.Add(0, list);

 

            list = new SegmentsList { 'B', 'C' };

            ValuesSegments.Add(1, list);

 

            list = new SegmentsList { 'A', 'B', 'G', 'E', 'D' };

            ValuesSegments.Add(2, list);

 

            list = new SegmentsList { 'A', 'B', 'G', 'C', 'D' };

            ValuesSegments.Add(3, list);

 

            list = new SegmentsList { 'F', 'G', 'B', 'C' };

            ValuesSegments.Add(4, list);

 

            list = new SegmentsList { 'A', 'F', 'G', 'C', 'D' };

            ValuesSegments.Add(5, list);

 

            list = new SegmentsList { 'A', 'F', 'G', 'C', 'D', 'E' };

            ValuesSegments.Add(6, list);

 

            list = new SegmentsList { 'A', 'B', 'C' };

            ValuesSegments.Add(7, list);

 

            list = new SegmentsList { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };

            ValuesSegments.Add(8, list);

 

            list = new SegmentsList { 'A', 'B', 'C', 'D', 'F', 'G' };

            ValuesSegments.Add(9, list);

 

            list = new SegmentsList { 'G' };

            ValuesSegments.Add('-', list);

 

            list = new SegmentsList { 'A', 'D', 'E', 'F', 'G' };

            ValuesSegments.Add('E', list);

        }

 

        #endregion

 

        #region Override Render Logic

 

        protected override void OnRender(DrawingContext drawingContext)

        {

            double rappW = ActualWidth / WIDTH_PIXEL;

            double rappH = ActualHeight / HEIGHT_PIXELS;

 

            var dotLocation = new Point

            {

                X = DefPoints[7].X * rappW,

                Y = DefPoints[8].Y * rappH +
0.5 * rappH,

            };

            var dotRadiusX = rappW * .8;

            var dotRadiusY = rappH * .8;

 

            var pth = new StreamGeometry();

            using (var sc = pth.Open())

            {

                foreach (Segment seg in Segments.Values)

                {

                    for (var idx = 0; idx < seg.PointsIndexs.Length; idx++)

                    {

                        var tmpPoint =
DefPoints[seg.PointsIndexs[idx]];

                        if (idx == 0)

                            sc.BeginFigure(new Point(tmpPoint.X * rappW,
tmpPoint.Y * rappH), true, true);

                        else

                            sc.LineTo(new Point(tmpPoint.X * rappW,
tmpPoint.Y * rappH), false, false);

                    }

                }

            }

            pth.Freeze();

            drawingContext.DrawRectangle(new SolidColorBrush(BackColor), null, new Rect(0, 0, ActualWidth,
ActualHeight));

            var offColor = ForeColor;

            offColor.A = 50;

            var offBrush = new SolidColorBrush(offColor);

           
drawingContext.DrawGeometry(offBrush, null, pth);

           
drawingContext.DrawEllipse(offBrush, null, dotLocation, dotRadiusX, dotRadiusY);

            if (ValuesSegments.Contains(Value))

            {

                var pth2 = new StreamGeometry();

                var list = ValuesSegments[Value];

                using (var sc = pth2.Open())

                {

                    foreach (var ch in list)

                    {

                        var seg = Segments[ch];

                        if (seg == null)

                            continue;

 

                        for (var idx = 0; idx <
seg.PointsIndexs.Length; idx++)

                        {

                            var tmpPoint =
DefPoints[seg.PointsIndexs[idx]];

                            if (idx == 0)

                                sc.BeginFigure(new Point(tmpPoint.X * rappW,
tmpPoint.Y * rappH), true, true);

                            else

                                sc.LineTo(new Point(tmpPoint.X * rappW,
tmpPoint.Y * rappH), false, false);

                        }

                    }

                }

                pth2.Freeze();

                var onBrush = new SolidColorBrush(ForeColor);

               
drawingContext.DrawGeometry(onBrush, null, pth2);

                if (ShowDot)

                   
drawingContext.DrawEllipse(onBrush, null, dotLocation, dotRadiusX, dotRadiusY);

            }

        }

 

        #endregion

    }

 

    #region Classes Used By DigitalDisplay

 

    /// <summary>

    /// Dictionary for the segment associated

    /// to the number

    /// </summary>

    public class SegmentDictionary : DictionaryBase

    {

        public Segment this[char ch]

        {

            set

            {

                if (Dictionary.Contains(ch) == false)

                    Add(ch, value);

                else

                    Dictionary[ch] = value;

            }

            get

            {

                if (Dictionary.Contains(ch) == false)

                    return null;

 

                return (Segment)Dictionary[ch];

            }

        }

 

        public void Add(char ch, Segment seg)

        {

            if (Contains(ch) == false)

                Dictionary.Add(ch, seg);

            else

                this[ch] = seg;

        }

 

        public bool Contains(char ch)

        {

            return Dictionary.Contains(ch);

        }

 

        public ICollection Values

        {

            get { return Dictionary.Values; }

        }

 

        public ICollection Keys

        {

            get { return Dictionary.Keys; }

        }

    }

 

    /// <summary>

    /// Class for the segment data

    /// </summary>

    public class Segment

    {

        private readonly int[] points = new int[6];

 

        public int[] PointsIndexs

        {

            get { return points; }

        }

    }

 

    /// <summary>

    /// Points list

    /// </summary>

    public class PointsList : List<Point>

    {

    }

 

    /// <summary>

    /// Segments list

    /// </summary>

    public class SegmentsList : List<char>

    {

    }

 

    /// <summary>

    /// Dictionary for value to segments

    /// </summary>

    public class SegmentsValueDictionary : DictionaryBase

    {

        public SegmentsList this[int num]

        {

            set

            {

                if (Dictionary.Contains(num) == false)

                    Add(num, value);

                else

                    Dictionary[num] = value;

            }

            get

            {

                if (Dictionary.Contains(num) == false)

                    return null;

 

                return (SegmentsList)Dictionary[num];

            }

        }

 

        public void Add(int num, SegmentsList seg)

        {

            if (Contains(num) == false)

                Dictionary.Add(num, seg);

            else

                this[num] = seg;

        }

 

        public bool Contains(int ch)

        {

            return Dictionary.Contains(ch);

        }

 

        public ICollection Values

        {

            get { return Dictionary.Values; }

        }

 

        public ICollection Keys

        {

            get { return Dictionary.Keys; }

        }

    }

 

    #endregion


使用

  <local:DigitalMeter   Grid.Row="3" Grid.Column="1" Value="34" BackColor="Black" ForeColor="Gold" FormatString="00.0" Signed="True" Margin="3"/>

本文地址:https://blog.csdn.net/u013104793/article/details/107610510

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网