【问题标题】:Radial slider UWP径向滑块 UWP
【发布时间】:2020-03-02 13:28:44
【问题描述】:

我想创建一个径向滑块。这是我写的代码,但我不明白我错在哪里。

MainPage.xaml:

<Grid>
    <Grid x:Name="GridBase" Width="207" Height="207">
        <Grid Height="207" Width="207" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Path Stroke="#FF34A1ED" StrokeThickness="7" x:Name="arcPath" StrokeEndLineCap="Round" StrokeStartLineCap="Round" RenderTransformOrigin="0.5,0.5">
                <Path.RenderTransform>
                    <CompositeTransform TranslateX="3.5" TranslateY="3.5"/>
                </Path.RenderTransform>
                <Path.Data>
                    <PathGeometry>
                        <PathFigure x:Name="myArcStart" StartPoint="7.612,61.6317">
                            <ArcSegment x:Name="myArc" IsLargeArc="true" Point="192.388,61.6317" Size="100,100"/>
                        </PathFigure>
                    </PathGeometry>
                </Path.Data>
            </Path>
        </Grid>
        <Canvas x:Name="CanvasVolume" Width="207" Height="207" RenderTransformOrigin="0.5,0.5">
            <Canvas.RenderTransform>
                <CompositeTransform x:Name="CompositePoint" Rotation="0"/>
            </Canvas.RenderTransform>
            <Ellipse x:Name="VolumePoint" Width="20" Height="20" Fill="#9923678A" PointerPressed="VolumePoint_PointerPressed" Canvas.Top="{x:Bind TopPosition, Mode=OneWay}" Canvas.Left="{x:Bind LeftPosition, Mode=OneWay}"/>
        </Canvas>
    </Grid>
</Grid>

MainPage.xaml.cs:

public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    private double topPosition = 55.2317;
    public double TopPosition
    {
        get => topPosition;
        set
        {
            topPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TopPosition)));
        }
    }

    private double leftPosition = 1.112;
    public double LeftPosition
    {
        get => leftPosition;
        set
        {
            leftPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LeftPosition)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public MainPage()
    {
        this.InitializeComponent();
    }



    private void VolumePoint_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        Point puntopressd = e.GetCurrentPoint(CanvasVolume).Position;

        PointerEventHandler moved = null;
        moved = (s, args) =>
        {
            CanvasVolume.CapturePointer(e.Pointer);
            Point puntomoved = e.GetCurrentPoint(CanvasVolume).Position;

            double puntoX = puntomoved.X;
            double puntoY = puntomoved.Y;
            double raggio = 100;

            if (puntoX < 100 && puntoY < 100)
            {
                double C1 = raggio - puntoY;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((C1 * C1) + (raggio * raggio) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio * (1 - Math.Sin(Beta));

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX < 100 && puntoY > 100)
            {
                double C1 = puntoY - raggio;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((raggio * raggio) + (C1 * C1) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio * (1 - Math.Sin(Beta));

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX > 100 && puntoY > 100)
            {
                double C1 = puntoY - raggio;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((raggio * raggio) + (C1 * C1) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio + C2;

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX > 100 && puntoY < 100)
            {
                double C1 = raggio - puntoY;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((C1 * C1) + (raggio * raggio) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio + C2;

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }

        };

        PointerEventHandler released = null;
        released = (s, args) =>
        {
            Point puntoreleas = e.GetCurrentPoint(CanvasVolume).Position;

            CanvasVolume.PointerMoved -= moved;
            CanvasVolume.PointerReleased -= released;
        };
        CanvasVolume.PointerMoved += moved;
        CanvasVolume.PointerReleased += released;
    }
}

椭圆从一侧移动到另一侧,在 0 度和 180 度的点处消失,我该如何解决?我认为问题在于提出的条件,但我不确定。

感谢您的帮助!

【问题讨论】:

    标签: c# uwp slider


    【解决方案1】:

    椭圆从一侧移动到另一侧,在 0 度和 180 度处消失。

    puntoX &gt; 100 and puntoY &gt; 100 中,有时函数Math.Sqrt((raggio * raggio) - (C1 * C1)) 会返回NaN。当 C1 属性值大于 raggio 时,平方值为负,则返回 NaN,椭圆消失。您可以从这一点解决这个问题。

    另外,我还有一个简单的变通方法,就是利用圆的一些特性来处理,可以让椭圆很好地移动。你可以试试下面的代码sn-p。

    moved = (s, args) =>
    {
        CanvasVolume.CapturePointer(e.Pointer);
        Point puntomoved = e.GetCurrentPoint(CanvasVolume).Position;
    
        double puntoX = puntomoved.X;
        double puntoY = puntomoved.Y;
        double raggio = 100;
    
        double halfWidth = CanvasVolume.ActualHeight / 2;
        double slashLength = Math.Sqrt((Math.Abs(puntoY - halfWidth) * Math.Abs(puntoY - halfWidth) + (Math.Abs(halfWidth - puntoX) * Math.Abs(halfWidth - puntoX))));
    
        LeftPosition = CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength) - VolumePoint.Width/2;
        TopPosition = puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength) - VolumePoint.Width / 2;
    
    };
    
    PointerEventHandler released = null;
    released = (s, args) =>
    {
        Point puntoreleas = e.GetCurrentPoint(CanvasVolume).Position;
    
        CanvasVolume.PointerMoved -= moved;
        CanvasVolume.PointerReleased -= released;
    };
    CanvasVolume.PointerMoved += moved;
    CanvasVolume.PointerReleased += released;
    

    【讨论】:

    • 感谢您的回复...我想问最后一件事。如何根据找到的坐标计算角度?
    • 您可以使用Math.Asin() 方法获取角度。首先得到两点之间的弦长,然后用Asin方法得到角度。
    猜你喜欢
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2012-04-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多