• Silverlight日记:字符串装换成Path对象


    一,需要动态绑定Path

     1 <UserControl x:Class="Secom.Emx2.SL.Common.Controls.EleSafe.Ele.Line"
     2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6     mc:Ignorable="d"
     7     d:DesignHeight="300" d:DesignWidth="400">
     8 
     9     <Path x:Name="myline" Stretch="Fill" Width="{Binding Width, ElementName=path, Mode=TwoWay}" Height="{Binding Height, ElementName=path, Mode=TwoWay}"/>
    10 </UserControl>

    二,生成Path

     1  private LineType _lineType = LineType.VLine;
     2         public LineType LineType
     3         {
     4             get
     5             {
     6                 return _lineType;
     7             }
     8             set
     9             {
    10                 _lineType = value;
    11                 var pathString = string.Empty;
    12                 var eff = new DropShadowEffect();
    13                 eff.BlurRadius = 5;
    14                 eff.Color = Colors.DarkGray;
    15                 eff.ShadowDepth = 0;
    16                 var conv = new StringToPathGeometryConverter();
    17                 switch (_lineType)
    18                 {
    19                     case LineType.HLine:
    20                         eff.Direction = 0;
    21                         pathString = "M0,0 L131.137,0";
    22                         break;
    23                     case LineType.VLine:
    24                     default:
    25                         eff.Direction = 90;
    26                         pathString = "M87,60 L87,240.178";
    27                         break;
    28                 }
    29 
    30                 var pathData = conv.Convert(pathString);
    31                 myline.SetValue(Path.DataProperty, pathData);
    32                 //myline.SetValue(Path.EffectProperty, eff);
    33             }
    34         }

    三,字符串转换成Path对象类

      1     /* ==============================
      2      * Desc:StringToPathGeometry  
      3      * Author:hezp
      4      * Date:2014/8/9 17:39:40
      5      * ==============================*/
      6     public class StringToPathGeometryConverter : IValueConverter
      7     {
      8         #region Const & Private Variables
      9         const bool AllowSign = true;
     10         const bool AllowComma = true;
     11         const bool IsFilled = true;
     12         const bool IsClosed = true;
     13 
     14         IFormatProvider _formatProvider;
     15 
     16         PathFigure _figure = null;     // Figure object, which will accept parsed segments
     17         string _pathString;        // Input string to be parsed
     18         int _pathLength;
     19         int _curIndex;          // Location to read next character from
     20         bool _figureStarted;     // StartFigure is effective 
     21 
     22         Point _lastStart;         // Last figure starting point
     23         Point _lastPoint;         // Last point 
     24         Point _secondLastPoint;   // The point before last point
     25 
     26         char _token;             // Non whitespace character returned by ReadToken
     27         #endregion
     28 
     29         #region Public Functionality
     30         /// <summary>
     31         /// Main conversion routine - converts string path data definition to PathGeometry object
     32         /// </summary>
     33         /// <param name="path">String with path data definition</param>
     34         /// <returns>PathGeometry object created from string definition</returns>
     35         public PathGeometry Convert(string path)
     36         {
     37             if (null == path)
     38                 throw new ArgumentException("Path string cannot be null!");
     39 
     40             if (path.Length == 0)
     41                 throw new ArgumentException("Path string cannot be empty!");
     42 
     43             return parse(path);
     44         }
     45 
     46         /// <summary>
     47         /// Main back conversion routine - converts PathGeometry object to its string equivalent
     48         /// </summary>
     49         /// <param name="geometry">Path Geometry object</param>
     50         /// <returns>String equivalent to PathGeometry contents</returns>
     51         public string ConvertBack(PathGeometry geometry)
     52         {
     53             if (null == geometry)
     54                 throw new ArgumentException("Path Geometry cannot be null!");
     55 
     56             return parseBack(geometry);
     57         }
     58         #endregion
     59 
     60         #region Private Functionality
     61         /// <summary>
     62         /// Main parser routine, which loops over each char in received string, and performs actions according to command/parameter being passed
     63         /// </summary>
     64         /// <param name="path">String with path data definition</param>
     65         /// <returns>PathGeometry object created from string definition</returns>
     66         private PathGeometry parse(string path)
     67         {
     68             PathGeometry _pathGeometry = null;
     69 
     70 
     71             _formatProvider = CultureInfo.InvariantCulture;
     72             _pathString = path;
     73             _pathLength = path.Length;
     74             _curIndex = 0;
     75 
     76             _secondLastPoint = new Point(0, 0);
     77             _lastPoint = new Point(0, 0);
     78             _lastStart = new Point(0, 0);
     79 
     80             _figureStarted = false;
     81 
     82             bool first = true;
     83 
     84             char last_cmd = ' ';
     85 
     86             while (ReadToken()) // Empty path is allowed in XAML
     87             {
     88                 char cmd = _token;
     89 
     90                 if (first)
     91                 {
     92                     if ((cmd != 'M') && (cmd != 'm') && (cmd != 'f') && (cmd != 'F'))  // Path starts with M|m 
     93                     {
     94                         ThrowBadToken();
     95                     }
     96 
     97                     first = false;
     98                 }
     99 
    100                 switch (cmd)
    101                 {
    102                     case 'f':
    103                     case 'F':
    104                         _pathGeometry = new PathGeometry();
    105                         double _num = ReadNumber(!AllowComma);
    106                         _pathGeometry.FillRule = _num == 0 ? FillRule.EvenOdd : FillRule.Nonzero;
    107                         break;
    108 
    109                     case 'm':
    110                     case 'M':
    111                         // XAML allows multiple points after M/m
    112                         _lastPoint = ReadPoint(cmd, !AllowComma);
    113 
    114                         _figure = new PathFigure();
    115                         _figure.StartPoint = _lastPoint;
    116                         _figure.IsFilled = IsFilled;
    117                         _figure.IsClosed = !IsClosed;
    118                         //context.BeginFigure(_lastPoint, IsFilled, !IsClosed);
    119                         _figureStarted = true;
    120                         _lastStart = _lastPoint;
    121                         last_cmd = 'M';
    122 
    123                         while (IsNumber(AllowComma))
    124                         {
    125                             _lastPoint = ReadPoint(cmd, !AllowComma);
    126 
    127                             LineSegment _lineSegment = new LineSegment();
    128                             _lineSegment.Point = _lastPoint;
    129                             _figure.Segments.Add(_lineSegment);
    130                             //context.LineTo(_lastPoint, IsStroked, !IsSmoothJoin);
    131                             last_cmd = 'L';
    132                         }
    133                         break;
    134 
    135                     case 'l':
    136                     case 'L':
    137                     case 'h':
    138                     case 'H':
    139                     case 'v':
    140                     case 'V':
    141                         EnsureFigure();
    142 
    143                         do
    144                         {
    145                             switch (cmd)
    146                             {
    147                                 case 'l': _lastPoint = ReadPoint(cmd, !AllowComma); break;
    148                                 case 'L': _lastPoint = ReadPoint(cmd, !AllowComma); break;
    149                                 case 'h': _lastPoint.X += ReadNumber(!AllowComma); break;
    150                                 case 'H': _lastPoint.X = ReadNumber(!AllowComma); break;
    151                                 case 'v': _lastPoint.Y += ReadNumber(!AllowComma); break;
    152                                 case 'V': _lastPoint.Y = ReadNumber(!AllowComma); break;
    153                             }
    154 
    155                             LineSegment _lineSegment = new LineSegment();
    156                             _lineSegment.Point = _lastPoint;
    157                             _figure.Segments.Add(_lineSegment);
    158                             //context.LineTo(_lastPoint, IsStroked, !IsSmoothJoin);
    159                         }
    160                         while (IsNumber(AllowComma));
    161 
    162                         last_cmd = 'L';
    163                         break;
    164 
    165                     case 'c':
    166                     case 'C': // cubic Bezier 
    167                     case 's':
    168                     case 'S': // smooth cublic Bezier
    169                         EnsureFigure();
    170 
    171                         do
    172                         {
    173                             Point p;
    174 
    175                             if ((cmd == 's') || (cmd == 'S'))
    176                             {
    177                                 if (last_cmd == 'C')
    178                                 {
    179                                     p = Reflect();
    180                                 }
    181                                 else
    182                                 {
    183                                     p = _lastPoint;
    184                                 }
    185 
    186                                 _secondLastPoint = ReadPoint(cmd, !AllowComma);
    187                             }
    188                             else
    189                             {
    190                                 p = ReadPoint(cmd, !AllowComma);
    191 
    192                                 _secondLastPoint = ReadPoint(cmd, AllowComma);
    193                             }
    194 
    195                             _lastPoint = ReadPoint(cmd, AllowComma);
    196 
    197                             BezierSegment _bizierSegment = new BezierSegment();
    198                             _bizierSegment.Point1 = p;
    199                             _bizierSegment.Point2 = _secondLastPoint;
    200                             _bizierSegment.Point3 = _lastPoint;
    201                             _figure.Segments.Add(_bizierSegment);
    202                             //context.BezierTo(p, _secondLastPoint, _lastPoint, IsStroked, !IsSmoothJoin);
    203 
    204                             last_cmd = 'C';
    205                         }
    206                         while (IsNumber(AllowComma));
    207 
    208                         break;
    209 
    210                     case 'q':
    211                     case 'Q': // quadratic Bezier 
    212                     case 't':
    213                     case 'T': // smooth quadratic Bezier
    214                         EnsureFigure();
    215 
    216                         do
    217                         {
    218                             if ((cmd == 't') || (cmd == 'T'))
    219                             {
    220                                 if (last_cmd == 'Q')
    221                                 {
    222                                     _secondLastPoint = Reflect();
    223                                 }
    224                                 else
    225                                 {
    226                                     _secondLastPoint = _lastPoint;
    227                                 }
    228 
    229                                 _lastPoint = ReadPoint(cmd, !AllowComma);
    230                             }
    231                             else
    232                             {
    233                                 _secondLastPoint = ReadPoint(cmd, !AllowComma);
    234                                 _lastPoint = ReadPoint(cmd, AllowComma);
    235                             }
    236 
    237                             QuadraticBezierSegment _quadraticBezierSegment = new QuadraticBezierSegment();
    238                             _quadraticBezierSegment.Point1 = _secondLastPoint;
    239                             _quadraticBezierSegment.Point2 = _lastPoint;
    240                             _figure.Segments.Add(_quadraticBezierSegment);
    241                             //context.QuadraticBezierTo(_secondLastPoint, _lastPoint, IsStroked, !IsSmoothJoin);
    242 
    243                             last_cmd = 'Q';
    244                         }
    245                         while (IsNumber(AllowComma));
    246 
    247                         break;
    248 
    249                     case 'a':
    250                     case 'A':
    251                         EnsureFigure();
    252 
    253                         do
    254                         {
    255                             // A 3,4 5, 0, 0, 6,7
    256                             double w = ReadNumber(!AllowComma);
    257                             double h = ReadNumber(AllowComma);
    258                             double rotation = ReadNumber(AllowComma);
    259                             bool large = ReadBool();
    260                             bool sweep = ReadBool();
    261 
    262                             _lastPoint = ReadPoint(cmd, AllowComma);
    263 
    264                             ArcSegment _arcSegment = new ArcSegment();
    265                             _arcSegment.Point = _lastPoint;
    266                             _arcSegment.Size = new Size(w, h);
    267                             _arcSegment.RotationAngle = rotation;
    268                             _arcSegment.IsLargeArc = large;
    269                             _arcSegment.SweepDirection = sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise;
    270                             _figure.Segments.Add(_arcSegment);
    271                             //context.ArcTo(
    272                             //    _lastPoint,
    273                             //    new Size(w, h),
    274                             //    rotation,
    275                             //    large,
    276                             //    sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise,
    277                             //    IsStroked,
    278                             //    !IsSmoothJoin
    279                             //    );
    280                         }
    281                         while (IsNumber(AllowComma));
    282 
    283                         last_cmd = 'A';
    284                         break;
    285 
    286                     case 'z':
    287                     case 'Z':
    288                         EnsureFigure();
    289                         _figure.IsClosed = IsClosed;
    290                         //context.SetClosedState(IsClosed);
    291 
    292                         _figureStarted = false;
    293                         last_cmd = 'Z';
    294 
    295                         _lastPoint = _lastStart; // Set reference point to be first point of current figure
    296                         break;
    297 
    298                     default:
    299                         ThrowBadToken();
    300                         break;
    301                 }
    302 
    303                 if (null != _figure)
    304                 {
    305                     if (_figure.IsClosed)
    306                     {
    307                         if (null == _pathGeometry)
    308                             _pathGeometry = new PathGeometry();
    309 
    310                         _pathGeometry.Figures.Add(_figure);
    311 
    312                         _figure = null;
    313                         first = true;
    314                     }
    315                 }
    316 
    317 
    318             }
    319 
    320             if (null != _figure)
    321             {
    322                 if (null == _pathGeometry)
    323                     _pathGeometry = new PathGeometry();
    324 
    325                 if (!_pathGeometry.Figures.Contains(_figure))
    326                     _pathGeometry.Figures.Add(_figure);
    327 
    328             }
    329             return _pathGeometry;
    330         }
    331 
    332         void SkipDigits(bool signAllowed)
    333         {
    334             // Allow for a sign 
    335             if (signAllowed && More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+'))
    336             {
    337                 _curIndex++;
    338             }
    339 
    340             while (More() && (_pathString[_curIndex] >= '0') && (_pathString[_curIndex] <= '9'))
    341             {
    342                 _curIndex++;
    343             }
    344         }
    345 
    346         bool ReadBool()
    347         {
    348             SkipWhiteSpace(AllowComma);
    349 
    350             if (More())
    351             {
    352                 _token = _pathString[_curIndex++];
    353 
    354                 if (_token == '0')
    355                 {
    356                     return false;
    357                 }
    358                 else if (_token == '1')
    359                 {
    360                     return true;
    361                 }
    362             }
    363 
    364             ThrowBadToken();
    365 
    366             return false;
    367         }
    368 
    369         private Point Reflect()
    370         {
    371             return new Point(2 * _lastPoint.X - _secondLastPoint.X,
    372                              2 * _lastPoint.Y - _secondLastPoint.Y);
    373         }
    374 
    375         private void EnsureFigure()
    376         {
    377             if (!_figureStarted)
    378             {
    379                 _figure = new PathFigure();
    380                 _figure.StartPoint = _lastStart;
    381 
    382                 //_context.BeginFigure(_lastStart, IsFilled, !IsClosed);
    383                 _figureStarted = true;
    384             }
    385         }
    386 
    387         double ReadNumber(bool allowComma)
    388         {
    389             if (!IsNumber(allowComma))
    390             {
    391                 ThrowBadToken();
    392             }
    393 
    394             bool simple = true;
    395             int start = _curIndex;
    396 
    397             //
    398             // Allow for a sign
    399             //
    400             // There are numbers that cannot be preceded with a sign, for instance, -NaN, but it's 
    401             // fine to ignore that at this point, since the CLR parser will catch this later.
    402             // 
    403             if (More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+'))
    404             {
    405                 _curIndex++;
    406             }
    407 
    408             // Check for Infinity (or -Infinity).
    409             if (More() && (_pathString[_curIndex] == 'I'))
    410             {
    411                 // 
    412                 // Don't bother reading the characters, as the CLR parser will 
    413                 // do this for us later.
    414                 // 
    415                 _curIndex = Math.Min(_curIndex + 8, _pathLength); // "Infinity" has 8 characters
    416                 simple = false;
    417             }
    418             // Check for NaN 
    419             else if (More() && (_pathString[_curIndex] == 'N'))
    420             {
    421                 // 
    422                 // Don't bother reading the characters, as the CLR parser will
    423                 // do this for us later. 
    424                 //
    425                 _curIndex = Math.Min(_curIndex + 3, _pathLength); // "NaN" has 3 characters
    426                 simple = false;
    427             }
    428             else
    429             {
    430                 SkipDigits(!AllowSign);
    431 
    432                 // Optional period, followed by more digits 
    433                 if (More() && (_pathString[_curIndex] == '.'))
    434                 {
    435                     simple = false;
    436                     _curIndex++;
    437                     SkipDigits(!AllowSign);
    438                 }
    439 
    440                 // Exponent
    441                 if (More() && ((_pathString[_curIndex] == 'E') || (_pathString[_curIndex] == 'e')))
    442                 {
    443                     simple = false;
    444                     _curIndex++;
    445                     SkipDigits(AllowSign);
    446                 }
    447             }
    448 
    449             if (simple && (_curIndex <= (start + 8))) // 32-bit integer
    450             {
    451                 int sign = 1;
    452 
    453                 if (_pathString[start] == '+')
    454                 {
    455                     start++;
    456                 }
    457                 else if (_pathString[start] == '-')
    458                 {
    459                     start++;
    460                     sign = -1;
    461                 }
    462 
    463                 int value = 0;
    464 
    465                 while (start < _curIndex)
    466                 {
    467                     value = value * 10 + (_pathString[start] - '0');
    468                     start++;
    469                 }
    470 
    471                 return value * sign;
    472             }
    473             else
    474             {
    475                 string subString = _pathString.Substring(start, _curIndex - start);
    476 
    477                 try
    478                 {
    479                     return System.Convert.ToDouble(subString, _formatProvider);
    480                 }
    481                 catch (FormatException except)
    482                 {
    483                     throw new FormatException(string.Format("Unexpected character in path '{0}' at position {1}", _pathString, _curIndex - 1), except);
    484                 }
    485             }
    486         }
    487 
    488         private bool IsNumber(bool allowComma)
    489         {
    490             bool commaMet = SkipWhiteSpace(allowComma);
    491 
    492             if (More())
    493             {
    494                 _token = _pathString[_curIndex];
    495 
    496                 // Valid start of a number
    497                 if ((_token == '.') || (_token == '-') || (_token == '+') || ((_token >= '0') && (_token <= '9'))
    498                     || (_token == 'I')  // Infinity
    499                     || (_token == 'N')) // NaN 
    500                 {
    501                     return true;
    502                 }
    503             }
    504 
    505             if (commaMet) // Only allowed between numbers
    506             {
    507                 ThrowBadToken();
    508             }
    509 
    510             return false;
    511         }
    512 
    513         private Point ReadPoint(char cmd, bool allowcomma)
    514         {
    515             double x = ReadNumber(allowcomma);
    516             double y = ReadNumber(AllowComma);
    517 
    518             if (cmd >= 'a') // 'A' < 'a'. lower case for relative
    519             {
    520                 x += _lastPoint.X;
    521                 y += _lastPoint.Y;
    522             }
    523 
    524             return new Point(x, y);
    525         }
    526 
    527         private bool ReadToken()
    528         {
    529             SkipWhiteSpace(!AllowComma);
    530 
    531             // Check for end of string 
    532             if (More())
    533             {
    534                 _token = _pathString[_curIndex++];
    535 
    536                 return true;
    537             }
    538             else
    539             {
    540                 return false;
    541             }
    542         }
    543 
    544         bool More()
    545         {
    546             return _curIndex < _pathLength;
    547         }
    548 
    549         // Skip white space, one comma if allowed
    550         private bool SkipWhiteSpace(bool allowComma)
    551         {
    552             bool commaMet = false;
    553 
    554             while (More())
    555             {
    556                 char ch = _pathString[_curIndex];
    557 
    558                 switch (ch)
    559                 {
    560                     case ' ':
    561                     case '
    ':
    562                     case '
    ':
    563                     case '	': // SVG whitespace 
    564                         break;
    565 
    566                     case ',':
    567                         if (allowComma)
    568                         {
    569                             commaMet = true;
    570                             allowComma = false; // one comma only
    571                         }
    572                         else
    573                         {
    574                             ThrowBadToken();
    575                         }
    576                         break;
    577 
    578                     default:
    579                         // Avoid calling IsWhiteSpace for ch in (' ' .. 'z']
    580                         if (((ch > ' ') && (ch <= 'z')) || !Char.IsWhiteSpace(ch))
    581                         {
    582                             return commaMet;
    583                         }
    584                         break;
    585                 }
    586 
    587                 _curIndex++;
    588             }
    589 
    590             return commaMet;
    591         }
    592 
    593         private void ThrowBadToken()
    594         {
    595             throw new FormatException(string.Format("Unexpected character in path '{0}' at position {1}", _pathString, _curIndex - 1));
    596         }
    597 
    598         static internal char GetNumericListSeparator(IFormatProvider provider)
    599         {
    600             char numericSeparator = ',';
    601 
    602             // Get the NumberFormatInfo out of the provider, if possible
    603             // If the IFormatProvider doesn't not contain a NumberFormatInfo, then 
    604             // this method returns the current culture's NumberFormatInfo. 
    605             NumberFormatInfo numberFormat = NumberFormatInfo.GetInstance(provider);
    606 
    607             // Is the decimal separator is the same as the list separator?
    608             // If so, we use the ";". 
    609             if ((numberFormat.NumberDecimalSeparator.Length > 0) && (numericSeparator == numberFormat.NumberDecimalSeparator[0]))
    610             {
    611                 numericSeparator = ';';
    612             }
    613 
    614             return numericSeparator;
    615         }
    616 
    617         private string parseBack(PathGeometry geometry)
    618         {
    619             System.Text.StringBuilder sb = new System.Text.StringBuilder();
    620             IFormatProvider provider = new System.Globalization.CultureInfo("en-us");
    621             string format = null;
    622 
    623             sb.Append("F" + (geometry.FillRule == FillRule.EvenOdd ? "0" : "1") + " ");
    624 
    625             foreach (PathFigure figure in geometry.Figures)
    626             {
    627                 sb.Append("M " + ((IFormattable)figure.StartPoint).ToString(format, provider) + " ");
    628 
    629                 foreach (PathSegment segment in figure.Segments)
    630                 {
    631                     char separator = GetNumericListSeparator(provider);
    632 
    633                     if (segment.GetType() == typeof(LineSegment))
    634                     {
    635                         LineSegment _lineSegment = segment as LineSegment;
    636 
    637                         sb.Append("L " + ((IFormattable)_lineSegment.Point).ToString(format, provider) + " ");
    638                     }
    639                     else if (segment.GetType() == typeof(BezierSegment))
    640                     {
    641                         BezierSegment _bezierSegment = segment as BezierSegment;
    642 
    643                         sb.Append(String.Format(provider,
    644                              "C{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "} ",
    645                              separator,
    646                              _bezierSegment.Point1,
    647                              _bezierSegment.Point2,
    648                              _bezierSegment.Point3
    649                              ));
    650                     }
    651                     else if (segment.GetType() == typeof(QuadraticBezierSegment))
    652                     {
    653                         QuadraticBezierSegment _quadraticBezierSegment = segment as QuadraticBezierSegment;
    654 
    655                         sb.Append(String.Format(provider,
    656                              "Q{1:" + format + "}{0}{2:" + format + "} ",
    657                              separator,
    658                              _quadraticBezierSegment.Point1,
    659                              _quadraticBezierSegment.Point2));
    660                     }
    661                     else if (segment.GetType() == typeof(ArcSegment))
    662                     {
    663                         ArcSegment _arcSegment = segment as ArcSegment;
    664 
    665                         sb.Append(String.Format(provider,
    666                              "A{1:" + format + "}{0}{2:" + format + "}{0}{3}{0}{4}{0}{5:" + format + "} ",
    667                              separator,
    668                              _arcSegment.Size,
    669                              _arcSegment.RotationAngle,
    670                              _arcSegment.IsLargeArc ? "1" : "0",
    671                              _arcSegment.SweepDirection == SweepDirection.Clockwise ? "1" : "0",
    672                              _arcSegment.Point));
    673                     }
    674                 }
    675 
    676                 if (figure.IsClosed)
    677                     sb.Append("Z");
    678             }
    679 
    680             return sb.ToString();
    681         }
    682         #endregion
    683 
    684         #region IValueConverter Members
    685 
    686         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    687         {
    688             string path = value as string;
    689             if (null != path)
    690                 return Convert(path);
    691             else
    692                 return null;
    693         }
    694 
    695         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    696         {
    697             PathGeometry geometry = value as PathGeometry;
    698 
    699             if (null != geometry)
    700                 return ConvertBack(geometry);
    701             else
    702                 return default(string);
    703         }
    704 
    705         #endregion
    706     }
    View Code
  • 相关阅读:
    Android中的sp与wp
    MTK
    linux kernel文件系统启动部分
    Java项目构建基础之统一结果
    线程和线程池的学习
    SpringBoot 中MyBatis的配置
    MyBatis中使用Map传参——返回值也是Map
    OAuth2的学习
    Java 跨域问题
    Spring Cloud 中的 eureka.instance.appname和spring.application.name 意思
  • 原文地址:https://www.cnblogs.com/mybluesky99/p/3939636.html
Copyright © 2020-2023  润新知