2016-05-17 47 views
1

我需要創建一個自定義的滑塊,此刻我的滑塊看上去正是我想要的,它看起來像這樣(從VisualStudio的圖像):自定義滑塊的Windows 8.1

enter image description here 螞蟻的XAML代碼是這樣的:

<Grid x:Name="mainGrid"> 
    <Grid Height="240" Width="300" Canvas.ZIndex="2"> 
     <Grid.RenderTransform> 
      <RotateTransform x:Name="rotateTransform" 
          Angle="-125" 
          CenterX="150" 
          CenterY="150" /> 
     </Grid.RenderTransform> 

     <Ellipse Height="54" Width="54" 
       x:Name="knob" 
       Fill="Red" 
       PointerMoved="Image_PointerMoved" 
       VerticalAlignment="Top" 
       Margin="0,-7,0,0"/> 
    </Grid> 

    <Path x:Name="path" 
      Data="M269.01,233.229 C303.532,181.303 304.261,118.855 269.097,67.0139 C207.933,-15.2077 92.8603,-16.8742 31.2108,66.0937 C-3.68835,121.514 -3.36331,179.271 30.8461,232.917 C51.2571,253.282 74.8965,230.573 61.3585,209.167 C38.2919,172.761 36.0008,129.688 62.1396,90.2093 C106.398,28.022 194.916,29.4803 237.509,90.1399 C262.554,127.345 263.613,170.209 237.647,209.792 C227.355,233.49 250.474,250.782 269.01,233.229 z" 
      Stretch="Fill" 
      Fill="Gray" /> 

</Grid> 

和C#代碼是這樣的:

private void Image_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
     //Canculate the current rotation angle and set the value. 
     var newPos = e.GetCurrentPoint(path); 
     double angle = GetAngleR(newPos.Position); 

     rotateTransform.Angle = angle; 
    } 

    public double GetAngleR(Point pos) 
    { 
     var xDiff = 150 - pos.X; 
     var yDiff = 150 - pos.Y; 
     var r = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff)); 

     var radians = Math.Acos((yDiff)/r); 

     var angle = radians * (180/Math.PI); 

     if(angle > 125) 
     { 
      angle = 125; 
     } 

     if(pos.X < 150) 
     { 
      angle = -angle; 
     } 

     return angle; 
    } 

我的問題是我如何填充不同的顏色路徑作爲我動橢圓?

我需要才達到somethig這樣的:

enter image description here

什麼建議嗎?

+0

哦,這看起來像一個整潔的一個!我可能會看direct2D的不透明面具。 –

回答

0

好吧我已經想出瞭如何做這個滑塊,這不是一個完美的解決方案,但它的作品,對我來說就足夠了。

我已經創建了一個GeometryGroup包含一些BezierSegment用於繪製拱形路徑,然後我添加了一個到該組的RectangleGeometry即該元件的大小。

在這種情況下GeometryGroup,兩個形狀的交叉區域沒有填充。

之後,我已將正確的顏色放在主路徑後面。

這是代碼:

XAML

<Grid x:Name="mainGrid"> 
    <Grid Height="240" Width="300" Canvas.ZIndex="2"> 
     <Grid.RenderTransform> 
      <RotateTransform x:Name="rotateTransform" 
          Angle="-125" 
          CenterX="150" 
          CenterY="150" /> 
     </Grid.RenderTransform> 

     <Image Height="54" Width="54" x:Name="knob" 
       Source="ms-appx:///Assets/ic_slider_credito.png" 
       PointerMoved="Image_PointerMoved" 
       VerticalAlignment="Top" 
       Margin="0,-5,0,0" /> 
    </Grid> 

    <Rectangle VerticalAlignment="Top" 
       HorizontalAlignment="Left" 
       Fill="Gray" 
       Width="300" 
       Height="240" /> 

    <Path x:Name="fillPath" 
      Height="240" 
      Width="300" 
      UseLayoutRounding="False" 
      VerticalAlignment="Top" 
      HorizontalAlignment="Left" 
      Fill="Orange" /> 

    <Path x:Name="path" 
      Height="240" 
      Width="300" 
      UseLayoutRounding="False" 
      Stretch="Fill" 
      Fill="White" /> 
</Grid> 

C#

public SliderInvioCredito() 
    { 
     this.InitializeComponent(); 
     DrawPath(); 
    } 

    private void Image_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
     var newPos = e.GetCurrentPoint(path); 
     double angle = GetAngleR(newPos.Position); 

     rotateTransform.Angle = angle; 
    } 

    public double GetAngleR(Point pos) 
    { 
     var xDiff = 150 - pos.X; 
     var yDiff = 150 - pos.Y; 
     var r = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff)); 

     var radians = Math.Acos((yDiff)/r); 

     var angle = radians * (180/Math.PI); 

     if (angle > 125) 
     { 
      angle = 125; 
     } 

     if (pos.X < 150) 
     { 
      angle = -angle; 
     } 

     DrawFillPath(pos.X, pos.Y, angle); 

     return angle; 
    } 

    private void DrawFillPath(double x, double y, double angle) 
    { 
     var start = new Point(150, 120); 
     var pth = new PathFigure(); 
     pth.StartPoint = start; 

     var ls1 = new LineSegment(); 
     ls1.Point = start; 
     pth.Segments.Add(ls1); 

     var ls8 = new LineSegment(); 
     ls8.Point = new Point(150, 240); 
     pth.Segments.Add(ls8); 

     var ls2 = new LineSegment(); 
     ls2.Point = new Point(0, 240); 
     pth.Segments.Add(ls2); 

     if (angle > -45) 
     { 
      var ls5 = new LineSegment(); 
      ls5.Point = new Point(0, 0); 
      pth.Segments.Add(ls5); 

      if (angle > -30) 
      { 
       var ls6 = new LineSegment(); 
       ls6.Point = new Point(x, 0); 
       pth.Segments.Add(ls6); 
      } 
     } 
     else 
     { 
      var ls3 = new LineSegment(); 
      ls3.Point = new Point(0, y); 
      pth.Segments.Add(ls3); 
     } 

     if (angle > 45) 
     { 
      var ls7 = new LineSegment(); 
      ls7.Point = new Point(300, 0); 
      pth.Segments.Add(ls7); 

      var ls9 = new LineSegment(); 
      ls9.Point = new Point(300, y); 
      pth.Segments.Add(ls9); 
     } 

     var ls4 = new LineSegment(); 
     ls4.Point = new Point(x, y); 
     pth.Segments.Add(ls4); 

     var pthCollection = new PathFigureCollection(); 
     pthCollection.Add(pth); 

     var pthGeometry = new PathGeometry(); 
     pthGeometry.Figures = pthCollection; 

     fillPath.Data = pthGeometry; 
    } 

    private void DrawPath() 
    { 
     var cc1 = new BezierSegment(); 
     cc1.Point1 = new Point(303.532, 181.303); 
     cc1.Point2 = new Point(304.261, 118.855); 
     cc1.Point3 = new Point(269.097, 67.0139); 

     var cc2 = new BezierSegment(); 
     cc2.Point1 = new Point(207.933, -15.2077); 
     cc2.Point2 = new Point(92.8603, -16.8742); 
     cc2.Point3 = new Point(31.2108, 66.0937); 

     var cc3 = new BezierSegment(); 
     cc3.Point1 = new Point(-3.68835, 121.514); 
     cc3.Point2 = new Point(-3.36331, 179.271); 
     cc3.Point3 = new Point(30.8461, 232.917); 

     var cc4 = new BezierSegment(); 
     cc4.Point1 = new Point(51.2571, 253.282); 
     cc4.Point2 = new Point(74.8965, 230.573); 
     cc4.Point3 = new Point(61.3585, 209.167); 

     var cc5 = new BezierSegment(); 
     cc5.Point1 = new Point(38.2919, 172.761); 
     cc5.Point2 = new Point(36.0008, 129.688); 
     cc5.Point3 = new Point(62.1396, 90.2093); 

     var cc6 = new BezierSegment(); 
     cc6.Point1 = new Point(106.398, 28.022); 
     cc6.Point2 = new Point(194.916, 29.4803); 
     cc6.Point3 = new Point(237.509, 90.1399); 

     var cc7 = new BezierSegment(); 
     cc7.Point1 = new Point(262.554, 127.345); 
     cc7.Point2 = new Point(263.613, 170.209); 
     cc7.Point3 = new Point(237.647, 209.792); 

     var cc8 = new BezierSegment(); 
     cc8.Point1 = new Point(227.355, 233.49); 
     cc8.Point2 = new Point(250.474, 250.782); 
     cc8.Point3 = new Point(269.01, 233.229); 

     var pthFigure = new PathFigure(); 
     pthFigure.StartPoint = new Point(269.01, 233.229); 

     var psc = new PathSegmentCollection(); 
     psc.Add(cc1); 
     psc.Add(cc2); 
     psc.Add(cc3); 
     psc.Add(cc4); 
     psc.Add(cc5); 
     psc.Add(cc6); 
     psc.Add(cc7); 
     psc.Add(cc8); 

     pthFigure.Segments = psc; 

     var pthFigureCollection = new PathFigureCollection(); 
     pthFigureCollection.Add(pthFigure); 

     var pthGeometry = new PathGeometry(); 
     pthGeometry.Figures = pthFigureCollection; 

     var rect = new RectangleGeometry(); 
     rect.Rect = new Rect(0, 0, 300, 240); 

     var gg = new GeometryGroup(); 
     gg.Children.Add(pthGeometry); 
     gg.Children.Add(rect); 

     path.Data = gg; 
    }