示例#1
0
        /// <summary>
        /// sets the tick values
        /// </summary>
        /// <param name="dc"></param>
        public override void Render(DrawingContext dc)
        {
            if (DoubleUtil.IsDoubleFinite(Width) == false)
            {
                this.Width = controlSize.Width;
                //base.Render(dc);
                //return;
            }

            Size   size    = new Size(Width, Height);
            double range   = Maximum - Minimum;
            double tickLen = 0.0d;  // Height for Primary Tick (for Mininum and Maximum value)
            double tickLen2;        // Height for Secondary Tick
            double logicalToPhysical = 1.0;
            double progression       = 1.0d;
            Point  startPoint        = new Point(0d, 0d);
            Point  endPoint          = new Point(0d, 0d);

            // Take Thumb size in to account
            double halfReservedSpace = ReservedSpace * 0.5;

            switch (Placement)
            {
            case TickBarPlacement.Top:
                if (DoubleUtil.GreaterThanOrClose(ReservedSpace, size.Width))
                {
                    return;
                }
                size              = new Size(size.Width - ReservedSpace, size.Height);
                tickLen           = -size.Height;
                startPoint        = new Point(halfReservedSpace, size.Height);
                endPoint          = new Point(halfReservedSpace + size.Width, size.Height);
                logicalToPhysical = size.Width / range;
                progression       = 1;
                break;

            case TickBarPlacement.Bottom:
                if (DoubleUtil.GreaterThanOrClose(ReservedSpace, size.Width))
                {
                    return;
                }
                size              = new Size(size.Width - ReservedSpace, size.Height);
                tickLen           = size.Height;
                startPoint        = new Point(halfReservedSpace, 0d);
                endPoint          = new Point(halfReservedSpace + size.Width, 0d);
                logicalToPhysical = size.Width / range;
                progression       = 1;
                break;

            case TickBarPlacement.Left:
                if (DoubleUtil.GreaterThanOrClose(ReservedSpace, size.Height))
                {
                    return;
                }
                size              = new Size(size.Width, size.Height - ReservedSpace);
                tickLen           = -size.Width;
                startPoint        = new Point(size.Width, size.Height + halfReservedSpace);
                endPoint          = new Point(size.Width, halfReservedSpace);
                logicalToPhysical = size.Height / range * -1;
                progression       = -1;
                break;

            case TickBarPlacement.Right:
                if (DoubleUtil.GreaterThanOrClose(ReservedSpace, size.Height))
                {
                    return;
                }
                size              = new Size(size.Width, size.Height - ReservedSpace);
                tickLen           = size.Width;
                startPoint        = new Point(0d, size.Height + halfReservedSpace);
                endPoint          = new Point(0d, halfReservedSpace);
                logicalToPhysical = size.Height / range * -1;
                progression       = -1;
                break;
            }
            ;

            tickLen2 = tickLen * 0.75;

            // Invert direciton of the ticks
            if (IsDirectionReversed)
            {
                progression        = -progression;
                logicalToPhysical *= -1;

                // swap startPoint & endPoint
                Point pt = startPoint;
                startPoint = endPoint;
                endPoint   = pt;
            }

            Pen pen = new Pen(Fill, 1.0d);

            bool             snapsToDevicePixels = false;//SnapsToDevicePixels
            DoubleCollection xLines = snapsToDevicePixels ? new DoubleCollection() : null;
            DoubleCollection yLines = snapsToDevicePixels ? new DoubleCollection() : null;

            // Is it Vertical?
            if ((Placement == TickBarPlacement.Left) || (Placement == TickBarPlacement.Right))
            {
                // Reduce tick interval if it is more than would be visible on the screen
                double interval = TickFrequency;
                if (interval > 0.0)
                {
                    double minInterval = (Maximum - Minimum) / size.Height;
                    if (interval < minInterval)
                    {
                        interval = minInterval;
                    }
                }

                // Draw Min & Max tick
                dc.DrawLine(pen, startPoint, new Point(startPoint.X + tickLen, startPoint.Y));
                dc.DrawLine(pen, new Point(startPoint.X, endPoint.Y),
                            new Point(startPoint.X + tickLen, endPoint.Y));

                if (snapsToDevicePixels)
                {
                    xLines.Add(startPoint.X);
                    yLines.Add(startPoint.Y - 0.5);
                    xLines.Add(startPoint.X + tickLen);
                    yLines.Add(endPoint.Y - 0.5);
                    xLines.Add(startPoint.X + tickLen2);
                }

                // This property is rarely set so let's try to avoid the GetValue
                // caching of the mutable default value
                DoubleCollection ticks = null;

                if (GetValue(TicksProperty)
                    != null)
                {
                    ticks = Ticks;
                }

                // Draw ticks using specified Ticks collection
                if ((ticks != null) && (ticks.Count > 0))
                {
                    for (int i = 0; i < ticks.Count; i++)
                    {
                        if (DoubleUtil.LessThanOrClose(ticks[i], Minimum) || DoubleUtil.GreaterThanOrClose(ticks[i], Maximum))
                        {
                            continue;
                        }

                        double adjustedTick = ticks[i] - Minimum;

                        double y = adjustedTick * logicalToPhysical + startPoint.Y;
                        dc.DrawLine(pen,
                                    new Point(startPoint.X, y),
                                    new Point(startPoint.X + tickLen2, y));

                        if (snapsToDevicePixels)
                        {
                            yLines.Add(y - 0.5);
                        }
                    }
                }
                // Draw ticks using specified TickFrequency
                else if (interval > 0.0)
                {
                    for (double i = interval; i < range; i += interval)
                    {
                        double y = i * logicalToPhysical + startPoint.Y;

                        dc.DrawLine(pen,
                                    new Point(startPoint.X, y),
                                    new Point(startPoint.X + tickLen2, y));

                        if (snapsToDevicePixels)
                        {
                            yLines.Add(y - 0.5);
                        }
                    }
                }

                // Draw Selection Ticks
                if (IsSelectionRangeEnabled)
                {
                    double y0  = (SelectionStart - Minimum) * logicalToPhysical + startPoint.Y;
                    Point  pt0 = new Point(startPoint.X, y0);
                    Point  pt1 = new Point(startPoint.X + tickLen2, y0);
                    Point  pt2 = new Point(startPoint.X + tickLen2, y0 + Math.Abs(tickLen2) * progression);

                    //PathSegment[] segments = new PathSegment[] {
                    //    //new LineSegment(pt2, true),
                    //    //new LineSegment(pt0, true),
                    //    new LineSegment{Point=pt2 },
                    //    new LineSegment{Point=pt0 },
                    //};

                    PathSegments segments = new PathSegments();
                    segments.Add(new LineSegment {
                        Point = pt2
                    });
                    segments.Add(new LineSegment {
                        Point = pt0
                    });

                    PathGeometry geo = new PathGeometry {
                        Figures = new PathFigures {
                            new PathFigure {
                                StartPoint = pt1, Segments = segments, IsClosed = true
                            }
                        }
                    };

                    dc.DrawGeometry(Fill, pen, geo);

                    y0  = (SelectionEnd - Minimum) * logicalToPhysical + startPoint.Y;
                    pt0 = new Point(startPoint.X, y0);
                    pt1 = new Point(startPoint.X + tickLen2, y0);
                    pt2 = new Point(startPoint.X + tickLen2, y0 - Math.Abs(tickLen2) * progression);

                    segments = new PathSegments();
                    segments.Add(new LineSegment {
                        Point = pt2
                    });
                    segments.Add(new LineSegment {
                        Point = pt0
                    });

                    geo = new PathGeometry {
                        Figures = new PathFigures {
                            new PathFigure {
                                StartPoint = pt1, Segments = segments, IsClosed = true
                            }
                        }
                    };
                    dc.DrawGeometry(Fill, pen, geo);
                }
            }
            else  // Placement == Top || Placement == Bottom
            {
                // Reduce tick interval if it is more than would be visible on the screen
                double interval = TickFrequency;
                if (interval > 0.0)
                {
                    double minInterval = (Maximum - Minimum) / size.Width;
                    if (interval < minInterval)
                    {
                        interval = minInterval;
                    }
                }

                // Draw Min & Max tick
                dc.DrawLine(pen, startPoint, new Point(startPoint.X, startPoint.Y + tickLen));
                dc.DrawLine(pen, new Point(endPoint.X, startPoint.Y),
                            new Point(endPoint.X, startPoint.Y + tickLen));

                if (snapsToDevicePixels)
                {
                    xLines.Add(startPoint.X - 0.5);
                    yLines.Add(startPoint.Y);
                    xLines.Add(startPoint.X - 0.5);
                    yLines.Add(endPoint.Y + tickLen);
                    yLines.Add(endPoint.Y + tickLen2);
                }

                // This property is rarely set so let's try to avoid the GetValue
                // caching of the mutable default value
                DoubleCollection ticks = null;

                if (GetValue(TicksProperty)
                    != null)
                {
                    ticks = Ticks;
                }

                // Draw ticks using specified Ticks collection
                if ((ticks != null) && (ticks.Count > 0))
                {
                    for (int i = 0; i < ticks.Count; i++)
                    {
                        if (DoubleUtil.LessThanOrClose(ticks[i], Minimum) || DoubleUtil.GreaterThanOrClose(ticks[i], Maximum))
                        {
                            continue;
                        }
                        double adjustedTick = ticks[i] - Minimum;

                        double x = adjustedTick * logicalToPhysical + startPoint.X;
                        dc.DrawLine(pen,
                                    new Point(x, startPoint.Y),
                                    new Point(x, startPoint.Y + tickLen2));

                        if (snapsToDevicePixels)
                        {
                            xLines.Add(x - 0.5);
                        }
                    }
                }
                // Draw ticks using specified TickFrequency
                else if (interval > 0.0)
                {
                    for (double i = interval; i < range; i += interval)
                    {
                        double x = i * logicalToPhysical + startPoint.X;
                        dc.DrawLine(pen,
                                    new Point(x, startPoint.Y),
                                    new Point(x, startPoint.Y + tickLen2));

                        if (snapsToDevicePixels)
                        {
                            xLines.Add(x - 0.5);
                        }
                    }
                }

                // Draw Selection Ticks
                if (IsSelectionRangeEnabled)
                {
                    double x0  = (SelectionStart - Minimum) * logicalToPhysical + startPoint.X;
                    Point  pt0 = new Point(x0, startPoint.Y);
                    Point  pt1 = new Point(x0, startPoint.Y + tickLen2);
                    Point  pt2 = new Point(x0 + Math.Abs(tickLen2) * progression, startPoint.Y + tickLen2);

                    //PathSegment[] segments = new PathSegment[] {
                    //    new LineSegment(pt2, true),
                    //    new LineSegment(pt0, true),
                    //};

                    PathSegments segments = new PathSegments();
                    segments.Add(new LineSegment {
                        Point = pt2
                    });
                    segments.Add(new LineSegment {
                        Point = pt0
                    });

                    PathGeometry geo = new PathGeometry {
                        Figures = new PathFigures {
                            new PathFigure {
                                StartPoint = pt1, Segments = segments, IsClosed = true
                            }
                        }
                    };

                    dc.DrawGeometry(Fill, pen, geo);

                    x0  = (SelectionEnd - Minimum) * logicalToPhysical + startPoint.X;
                    pt0 = new Point(x0, startPoint.Y);
                    pt1 = new Point(x0, startPoint.Y + tickLen2);
                    pt2 = new Point(x0 - Math.Abs(tickLen2) * progression, startPoint.Y + tickLen2);

                    segments = new PathSegments();
                    segments.Add(new LineSegment {
                        Point = pt2
                    });
                    segments.Add(new LineSegment {
                        Point = pt0
                    });

                    geo = new PathGeometry {
                        Figures = new PathFigures {
                            new PathFigure {
                                StartPoint = pt1, Segments = segments, IsClosed = true
                            }
                        }
                    };
                    dc.DrawGeometry(Fill, pen, geo);
                }
            }

            if (snapsToDevicePixels)
            {
                xLines.Add(Width);
                yLines.Add(Height);
                VisualXSnappingGuidelines = xLines;
                VisualYSnappingGuidelines = yLines;
            }
            return;
        }
        // Sets Value = SnapToTick(value+direction), unless the result of SnapToTick is Value,
        // then it searches for the next tick greater(if direction is positive) than value
        // and sets Value to that tick
        private void MoveToNextTick(double direction)
        {
            if (direction != 0.0)
            {
                double value = this.Value;

                // Find the next value by snapping
                double next = SnapToTick(Math.Max(this.Minimum, Math.Min(this.Maximum, value + direction)));

                bool greaterThan = direction > 0; //search for the next tick greater than value?

                // If the snapping brought us back to value, find the next tick point
                if (next == value &&
                    !(greaterThan && value == Maximum) &&  // Stop if searching up if already at Max
                    !(!greaterThan && value == Minimum))    // Stop if searching down if already at Min
                {
                    // This property is rarely set so let's try to avoid the GetValue
                    // caching of the mutable default value
                    DoubleCollection ticks = null;

                    if (GetValue(TicksProperty)
                        != null)
                    {
                        ticks = Ticks;
                    }

                    // If ticks collection is available, use it.
                    // Note that ticks may be unsorted.
                    if ((ticks != null) && (ticks.Count > 0))
                    {
                        for (int i = 0; i < ticks.Count; i++)
                        {
                            double tick = ticks[i];

                            // Find the smallest tick greater than value or the largest tick less than value
                            if ((greaterThan && DoubleUtil.GreaterThan(tick, value) && (DoubleUtil.LessThan(tick, next) || next == value)) ||
                                (!greaterThan && DoubleUtil.LessThan(tick, value) && (DoubleUtil.GreaterThan(tick, next) || next == value)))
                            {
                                next = tick;
                            }
                        }
                    }
                    else if (DoubleUtil.GreaterThan(TickFrequency, 0.0))
                    {
                        // Find the current tick we are at
                        double tickNumber = Math.Round((value - Minimum) / TickFrequency);

                        if (greaterThan)
                        {
                            tickNumber += 1.0;
                        }
                        else
                        {
                            tickNumber -= 1.0;
                        }

                        next = Minimum + tickNumber * TickFrequency;
                    }
                }

                // Update if we've found a better value
                if (next != value)
                {
                    this.SetValue(ValueProperty, next);
                }
            }
        }