zoukankan      html  css  js  c++  java
  • wpf做的标尺

    wpf是微软下一代的window开发平台,或者说是xaml,毕竟c++以后也支持了,在想directUI这种东西以后还会有人用吗?

    因为我主要负责的是编辑器的工作,所以需要做一个标尺,下面先看下我做的效果吧


    提供三个属性
    DisplayPercent 当前显示比例
    DisplayType  显示方式 横向/竖向
    ZeroPoint 选择0点位置

    可选属性
    Dpi
    用于确定系统目前的Dpi,来让像素转换为cm
    目前还不支持Cm/Pixel切换
    现在只支持Pixel的显示

    代码比较少,直接文章里上,欢迎大家使用,转载的话希望注明出处,谢谢了哈wpf做的标尺,【顺便分享代码一枚】 - 转载注明出处 gsralex.blog.163.com

     

     

    /*
     * ///////////////////////////////////////
     * ///////////////////////////////////////
     * ///////////////////////////////////////
     * 转载注明出处 gsralex.blog.163.com//
     * ///////////////////////////////////////
     * ///////////////////////////////////////
     * ///////////////////////////////////////
     */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Globalization;
    
    namespace GsrAlex
    {
        public class GsrAlexStaff : Control
        {
            public static readonly DependencyProperty    DpiProperty        = DependencyProperty.Register( "Dpi", typeof(Dpi), typeof(GsrAlexStaff) );
            public static readonly DependencyProperty    DisplayPercentProperty    = DependencyProperty.Register( "DisplayPercent", typeof(double), typeof(GsrAlexStaff) );
            public static readonly DependencyProperty    DisplayTypeProperty    = DependencyProperty.Register( "DisplayType", typeof(StaffDisplayType), typeof(GsrAlexStaff) );
            public static readonly DependencyProperty    DisplayUnitProperty    = DependencyProperty.Register( "DisplayUnit", typeof(StaffDisplayUnit), typeof(GsrAlexStaff) );
            public static readonly DependencyProperty    ZeroPointProperty    = DependencyProperty.Register( "ZeroPoint", typeof(double), typeof(GsrAlexStaff) );
    
            static GsrAlexStaff()
            {
                DefaultStyleKeyProperty.OverrideMetadata( typeof(GsrAlexStaff), new FrameworkPropertyMetadata( typeof(GsrAlexStaff) ) );
            }
    
    
            #region 属性
    
    /*
     * / <summary>
     * / Dpi
     * / </summary>
     */
            public Dpi Dpi
            {
                get
                {
                    return( (Dpi) GetValue( DpiProperty ) );
                }
                set
                {
                    SetValue( DpiProperty, value );
                }
            }
    
            public double ZeroPoint
            {
                get
                {
                    return( (double) GetValue( ZeroPointProperty ) );
                }
                set
                {
                    SetValue( ZeroPointProperty, value );
                    InvalidateVisual();
                }
            }
    
    /*
     * / <summary>
     * / 显示比例
     * / </summary>
     */
            public double DisplayPercent
            {
                get
                {
                    return( (double) GetValue( DisplayPercentProperty ) );
                }
                set
                {
                    SetValue( DisplayPercentProperty, value );
                }
            }
    
    /*
     * / <summary>
     * / 显示类型
     * / </summary>
     */
            public StaffDisplayType DisplayType
            {
                get
                {
                    return( (StaffDisplayType) GetValue( DisplayTypeProperty ) );
                }
                set
                {
                    SetValue( DisplayTypeProperty, value );
                }
            }
    
    /*
     * / <summary>
     * / 显示单位
     * / </summary>
     */
            public StaffDisplayUnit DisplayUnit
            {
                get
                {
                    return( (StaffDisplayUnit) GetValue( DisplayUnitProperty ) );
                }
                set
                {
                    SetValue( DisplayUnitProperty, value );
                }
            }
    
    
            #endregion
    
            #region 常量
    
            public const double    _inchCm            = 2.54;
            private const int    _p100StepSpanPixel    = 100;
            private const int    _p100StepSpanCm        = 2;
            private const int    _p100StepCountPixel    = 20;
            private const int    _p100StepCountCm    = 20;
    
            #endregion
    
            #region 变量
    
    /*
     * / <summary>
     * / 1cm显示的像素数除以步进跨度的系数
     * / </summary>
     */
            private double _minRatio;
    /*
     * / <summary>
     * / 1cm显示的像素数除以步进跨度的系数
     * / </summary>
     */
            private double _maxRatio;
    
            private double _minStepLengthCm;
    
            private double _maxStepLengthCm;
    
            private double        _actualLength;
            private int        _stepSpan;
            private int        _stepCount;
            private double        _stepLength;
            private bool        _isInvalidateVisual;
            private Point        _lastPoint;
            private Position    _lastPosition;
    
    
            #endregion
    
    
            protected override void OnRender( DrawingContext drawingContext )
            {
                try
                {
                    Pen pen = new Pen( new SolidColorBrush( Colors.Black ), 0.5d );
                    pen.Freeze();
    
                    base.OnRender( drawingContext );
    
                    Initialize();
                    GetStep();
                    GetActualLength();
    
                    this.BorderBrush    = new SolidColorBrush( Colors.Black );
                    this.BorderThickness    = new Thickness( 0.5 );
    /* this.Background = new SolidColorBrush(Colors.White); */
    
    
                    #region try
    
                    double actualPx = this._actualLength / DisplayPercent;
    
    
                    Position currentPosition = new Position {
                        CurrentStepIndex = 0, Value = 0
                    };
    
                    switch ( DisplayType )
                    {
                    case StaffDisplayType.Horizontal:
                    {
    /* 绘制前半段 */
                        DrawLine( drawingContext, ZeroPoint, currentPosition, pen, 0 );
    /* 绘制后半段 */
                        DrawLine( drawingContext, ZeroPoint, currentPosition, pen, 1 );
    
    
                        break;
                    }
                    case StaffDisplayType.Vertical:
                    {
    /* 绘制前半段 */
                        DrawLine( drawingContext, ZeroPoint, currentPosition, pen, 0 );
    /* 绘制后半段 */
                        DrawLine( drawingContext, ZeroPoint, currentPosition, pen, 1 );
    
                        break;
                    }
                    }
    
    
                    #endregion
                }
                catch ( Exception ex )
                {
                    Console.WriteLine( ex.Message );
                }
            }
    
    
            private void DrawLine( DrawingContext drawingContext, double currentPoint, Position currentPosition, Pen pen, int type )
            {
                double linePercent = 0d;
    
                while ( true )
                {
                    if ( currentPosition.CurrentStepIndex == 0 )
                    {
                        linePercent = (int) LinePercent.P100;
                        FormattedText formattedText = GetFormattedText( currentPosition.Value.ToString() );
    
                        switch ( DisplayType )
                        {
                        case StaffDisplayType.Horizontal:
                        {
                            drawingContext.DrawText( formattedText, new Point( currentPoint + formattedText.Width / 2, formattedText.Height / 3 ) );
                            break;
                        }
                        case StaffDisplayType.Vertical:
                        {
                            Point        point        = new Point( this.ActualWidth, currentPoint + formattedText.Height / 2 );
                            RotateTransform rotateTransform = new RotateTransform( 90, point.X, point.Y );
                            drawingContext.PushTransform( rotateTransform );
                            drawingContext.DrawText( formattedText, point );
                            drawingContext.Pop();
                            break;
                        }
                        }
    
    
                        linePercent = (int) LinePercent.P100;
                    }else if ( IsFinalNum( currentPosition.CurrentStepIndex, 3 ) )
                    {
                        linePercent = (int) LinePercent.P30;
                    }else if ( IsFinalNum( currentPosition.CurrentStepIndex, 5 ) )
                    {
                        linePercent = (int) LinePercent.P50;
                    }else if ( IsFinalNum( currentPosition.CurrentStepIndex, 7 ) )
                    {
                        linePercent = (int) LinePercent.P30;
                    }else if ( IsFinalNum( currentPosition.CurrentStepIndex, 0 ) )
                    {
                        linePercent = (int) LinePercent.P70;
                    }else  {
                        linePercent = (int) LinePercent.P20;
                    }
    
                    linePercent = linePercent * 0.01;
    
                    if ( linePercent == 1 )
                    {
                    }
    
    
                    switch ( DisplayType )
                    {
                    case StaffDisplayType.Horizontal:
                    {
                        drawingContext.DrawLine( pen, new Point( currentPoint, 0 ), new Point( currentPoint, this.ActualHeight * linePercent ) );
    
                        if ( type == 0 )
                        {
                            currentPoint = currentPoint - _stepLength;
                            currentPosition.CurrentStepIndex--;
    
                            if ( currentPosition.CurrentStepIndex < 0 )
                            {
                                currentPosition.CurrentStepIndex    = _stepCount - 1;
                                currentPosition.Value            = GetNextStepValue( currentPosition.Value, _stepSpan, 0 );
                            }else if ( currentPosition.CurrentStepIndex == 0 )
                            {
                                if ( currentPosition.Value % _stepSpan != 0 )
                                    currentPosition.Value = GetNextStepValue( currentPosition.Value, _stepSpan, 0 );
                            }
    
                            if ( currentPoint <= 0 )
                            {
                                return;
                            }
                        }else  {
                            currentPoint = currentPoint + _stepLength;
                            currentPosition.CurrentStepIndex++;
    
                            if ( currentPosition.CurrentStepIndex >= _stepCount )
                            {
                                currentPosition.CurrentStepIndex    = 0;
                                currentPosition.Value            = GetNextStepValue( currentPosition.Value, _stepSpan, 1 );
                            }
    
                            if ( currentPoint >= _actualLength )
                            {
                                return;
                            }
                        }
                        break;
                    }
                    case StaffDisplayType.Vertical:
                    {
                        drawingContext.DrawLine( pen, new Point( 0, currentPoint ), new Point( this.ActualWidth * linePercent, currentPoint ) );
    
                        if ( type == 0 )
                        {
                            currentPoint = currentPoint - _stepLength;
                            currentPosition.CurrentStepIndex--;
    
                            if ( currentPosition.CurrentStepIndex < 0 )
                            {
                                currentPosition.CurrentStepIndex    = _stepCount - 1;
                                currentPosition.Value            = GetNextStepValue( currentPosition.Value, _stepSpan, 0 );
                            }else if ( currentPosition.CurrentStepIndex == 0 )
                            {
                                if ( currentPosition.Value % _stepSpan != 0 )
                                    currentPosition.Value = GetNextStepValue( currentPosition.Value, _stepSpan, 0 );
                            }
    
                            if ( currentPoint <= 0 )
                            {
                                return;
                            }
                        }else  {
                            currentPoint = currentPoint + _stepLength;
                            currentPosition.CurrentStepIndex++;
    
                            if ( currentPosition.CurrentStepIndex >= _stepCount )
                            {
                                currentPosition.CurrentStepIndex    = 0;
                                currentPosition.Value            = GetNextStepValue( currentPosition.Value, _stepSpan, 1 );
                            }
    
                            if ( currentPoint >= _actualLength )
                            {
                                return;
                            }
                        }
                        break;
                    }
                    }
                }
            }
    
    
            private int GetNextStepValue( int value, int times, int type )
            {
                if ( type == 0 )
                {
                    do
                    {
                        value--;
                    }
                    while ( value % times != 0 );
                }else  {
                    do
                    {
                        value++;
                    }
                    while ( value % times != 0 );
                }
    
    
                return(value);
            }
    
    
            private FormattedText GetFormattedText( string text )
            {
                return(new FormattedText( text,
                              CultureInfo.GetCultureInfo( "zh-cn" ),
                              FlowDirection.LeftToRight,
                              new Typeface( "Microsoft YaHei" ),
                              8,
                              Brushes.Black ) );
            }
    
    
            private bool IsFinalNum( int value, int finalNum )
            {
                string valueStr = value.ToString();
                if ( valueStr.Substring( valueStr.Length - 1, 1 ) == finalNum.ToString() )
                {
                    return(true);
                }
                return(false);
            }
    
    
            private void Initialize()
            {
                Dpi dpi = new Dpi();
                dpi.DpiX    = Dpi.DpiX;
                dpi.DpiY    = Dpi.DpiY;
                if ( Dpi.DpiX == 0 )
                {
                    dpi.DpiX = 96;
                }
    
                if ( Dpi.DpiY == 0 )
                {
                    dpi.DpiY = 96;
                }
    
                Dpi = dpi;
    
                _maxRatio = 1 / _inchCm * GetDpi() / 80;
    
    
                _minRatio = 1 / _inchCm * GetDpi() / 200;
    
    
                _minStepLengthCm    = 0.1;
                _maxStepLengthCm    = 0.3;
    
    
                if ( DisplayPercent == 0 )
                    DisplayPercent = 1;
    
    
                switch ( DisplayUnit )
                {
                case StaffDisplayUnit.pixel:
                {
                    _stepSpan    = _p100StepSpanPixel;
                    _stepCount    = _p100StepCountPixel;
                    break;
                }
                case StaffDisplayUnit.cm:
                {
                    _stepSpan    = _p100StepSpanCm;
                    _stepCount    = _p100StepCountCm;
                    break;
                }
                }
    
                int width = 15;
    
                switch ( DisplayType )
                {
                case StaffDisplayType.Horizontal:
                {
                    if ( this.ActualHeight == 0 )
                    {
                        Height = width;
                    }
                    break;
                }
                case StaffDisplayType.Vertical:
                {
                    if ( this.ActualWidth == 0 )
                    {
                        Width = width;
                    }
                    break;
                }
                }
            }
    
    
            private void GetStep()
            {
                switch ( DisplayUnit )
                {
                case StaffDisplayUnit.pixel:
                {
    /* 100px */
                    _stepSpan    = 100;
                    _stepCount    = 20;
    
    /* 求出当前跨度应该显示的cm */
                    double stepSpanCm = _stepSpan / Common.Utility.ConvertDouble( GetDpi() ) * _inchCm * DisplayPercent;
    
    
                    while ( true )
                    {
                        stepSpanCm = _stepSpan / Common.Utility.ConvertDouble( GetDpi() ) * _inchCm * DisplayPercent;
                        double    stepLengthCm    = stepSpanCm / _stepCount;
                        int    type        = 0;
                        bool    isOut        = false;
                        if ( stepLengthCm > _maxStepLengthCm )
                        {
                            type        = 1;
                            _stepCount    = GetNextStepCount( _stepCount, type, ref isOut );
                        }
    
                        if ( stepLengthCm < _minStepLengthCm )
                        {
                            type        = 0;
                            _stepCount    = GetNextStepCount( _stepCount, type, ref isOut );
                        }
    
                        if ( stepLengthCm <= _maxStepLengthCm && stepLengthCm >= _minStepLengthCm )
                        {
                            _stepLength = stepSpanCm / _inchCm * GetDpi() / _stepCount;
    
    
                            break;
                        }
    
    /* 已超出或小于最大步进长度 */
                        if ( isOut )
                        {
                            _stepSpan = GetNextStepSpan( _stepSpan, type );
                            continue;
                        }
                    }
    
    
                    break;
                }
                }
            }
    
    
            private int GetNextStepCount( int stepCount, int type, ref bool isOut )
            {
                int result = stepCount;
                isOut = false;
    
                switch ( type )
                {
                case 0:
                {
                    if ( stepCount == 20 )
                    {
                        result = 10;
                    }else  {
                        isOut = true;
                    }
                    break;
                }
                case 1:
                {
                    if ( stepCount == 10 )
                    {
                        result = 20;
                    }else  {
                        isOut = true;
                    }
    
                    break;
                }
                }
    
                return(result);
            }
    
    
            private int GetNextStepSpan( int stepSpan, int type )
            {
    /* 100 200 500 */
                string    stepCountStr    = stepSpan.ToString();
                string    resultStr    = string.Empty;
    
                switch ( DisplayUnit )
                {
                case StaffDisplayUnit.pixel:
                {
                    switch ( type )
                    {
                    case 0:
                    {
                        if ( stepCountStr.IndexOf( '5' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 1, stepCountStr.Length );
                        }else if ( stepCountStr.IndexOf( '2' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 5, stepCountStr.Length - 1 );
                        }else if ( stepCountStr.IndexOf( '1' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 2, stepCountStr.Length - 1 );
                        }
                        break;
                    }
                    case 1:
                    {
                        if ( stepCountStr.IndexOf( '5' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 2, stepCountStr.Length - 1 );
                        }else if ( stepCountStr.IndexOf( '2' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 1, stepCountStr.Length - 1 );
                        }else if ( stepCountStr.IndexOf( '1' ) > -1 )
                        {
                            resultStr = GetNumberAndZeroNum( 5, stepCountStr.Length - 2 );
                        }
                        break;
                    }
                    }
    
                    break;
                }
                }
    
                return(Common.Utility.ConvertInt( resultStr ) );
            }
    
    
            private string GetNumberAndZeroNum( int num, int zeroNum )
            {
                string result = string.Empty;
                result += num;
                for ( int i = 0; i < zeroNum; i++ )
                {
                    result += "0";
                }
    
                return(result);
            }
    
    
            private int GetDpi()
            {
                switch ( DisplayType )
                {
                case StaffDisplayType.Horizontal:
                {
                    return(Dpi.DpiX);
                }
                case StaffDisplayType.Vertical:
                {
                    return(Dpi.DpiY);
                }
                default:
                {
                    return(Dpi.DpiX);
                }
                }
            }
    
    
            private void GetActualLength()
            {
                switch ( DisplayType )
                {
                case StaffDisplayType.Horizontal:
                {
                    _actualLength = this.ActualWidth;
                    break;
                }
                case StaffDisplayType.Vertical:
                {
                    _actualLength = this.ActualHeight;
                    break;
                }
                }
            }
        }
    
    
        public enum StaffDisplayType
        {
            Horizontal, Vertical
        }
    
        public enum StaffDisplayUnit
        {
            cm, pixel
        }
    
        public enum LinePercent
        {
            P20 = 20, P30 = 30, P50 = 50, P70 = 70, P100 = 100
        }
    
        public struct Dpi
        {
            public int DpiX {
                get; set;
            }
            public int DpiY {
                get; set;
            }
        }
    
        public struct Position
        {
            public int Value {
                get; set;
            }
            public int CurrentStepIndex {
                get; set;
            }
        }
    }
     
     

    2012年7月14 于郑州 天气:晴

    博客搬家从blog.163.com/gsralex 搬家到 www.cnblogs.com/gsralex
    博文全部为原创,谢绝一切转载
  • 相关阅读:
    Redis string
    java 是 传值还是传址 Pass-by-value or Pass-by-reference
    IDEA 适用技巧
    测试 MD
    pyqt5 学习总结
    win10 安装anaconda 无法使用pip 报错缺少SSL模块
    Hadoop datanode无法启动
    Ansible 安装jdk
    java 安装后 不能 java javac 说找不到命令 -bash: javac: command not found
    如何去掉MapReduce输出的默认分隔符
  • 原文地址:https://www.cnblogs.com/gsralex/p/3538043.html
Copyright © 2011-2022 走看看