所以我有Circular Progress-Bar
,我希望Label
围绕圈Value
定位。
这就是我的尝试:
<Grid x:Name="LayoutRoot" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" SegmentColor="#FF878889" StrokeThickness="25" Percentage="100" Radius="100"/>
<DesignInControl:CircularProgressBar x:Name="circle" HorizontalAlignment="Center" VerticalAlignment="Center" Percentage="0" SegmentColor="Red" StrokeThickness="25" Radius="100"/>
</Grid>
</StackPanel>
<Label x:Name="vlb" Content="{Binding ElementName=circle, Path=Percentage}" Margin="-50,-50,-50,-50" RenderTransformOrigin="0.5,0.5" Grid.RowSpan="2">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="3600.12"/>
<TranslateTransform/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</Grid>
现在在我的Timer
里面,我每秒将Circelr百分比提高1:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
double d = circle.Percentage += 1;
var radius = 100;
var sangle = (d * 360) / 100;
double angleRad = (Math.PI / 180.0) * (sangle - 90);
double x = radius * Math.Cos(angleRad);
double y = radius * Math.Sin(angleRad);
vlb.RenderTransform = new RotateTransform { Angle = sangle, CenterX = 0, CenterY = 0 };
}
结果是我的Label
现在是直的:
更新
<Grid x:Name="LayoutRoot" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" SegmentColor="#FF878889" StrokeThickness="25" Percentage="100" Radius="100"/>
<DesignInControl:CircularProgressBar x:Name="circle" HorizontalAlignment="Center" VerticalAlignment="Center" Percentage="0" SegmentColor="SeaGreen" StrokeThickness="25" Radius="100"/>
</Grid>
</StackPanel>
<Label x:Name="vlb_outer" Margin="-50,-50,-50,-50" RenderTransformOrigin="0.5,0.5" Grid.RowSpan="2">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="50"/>
<TranslateTransform/>
</TransformGroup>
</Label.RenderTransform>
<Label Content="{Binding ElementName=circle, Path=Percentage}" FontSize="20" x:Name="vlb_inner">
<Label.RenderTransform>
<TransformGroup>
<RotateTransform Angle="-50"/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</Label>
</Grid>
结果
Update
开始位置:
Value
之后1
加注:
Label
左侧尺寸很小。
答案 0 :(得分:0)
之前我从未在wpf中使用过变换,但由于我有游戏开发背景,这对我来说很容易处理:
我创建了一个孩子 - Label
,它具有绑定和自己的TransformGroup
,如下所示:
<Label x:Name="vlb_outer" Margin="-50,-50,-50,-50" RenderTransformOrigin="0.5,0.5" Grid.RowSpan="2">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="50"/>
<TranslateTransform/>
</TransformGroup>
</Label.RenderTransform>
<Label Content="{Binding Value}" x:Name="vlb_inner">
<Label.RenderTransform>
<TransformGroup>
<RotateTransform Angle="-50"/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</Label>
现在我在代码中所做的很简单,我只是将rotationvalue分配给vlb_outer
元素,将负旋转值分配给vlb_inner
元素。通过这种方式,它将围绕其自身的中心向相反方向旋转相同的角度。
vlb_outer.RenderTransform = new RotateTransform() { Angle = value };
vlb_inner.RenderTransform = new RotateTransform() { Angle = -value };
我为我简化了所有内容,因为我没有您的代码,但它似乎有效。我尝试使用0到360之间的滑块,并将值绑定到Content
和旋转。
希望它有所帮助。
修改强>
好吧,因为你不喜欢这个位置(显然),我玩弄了我的计算并信任我,我讨厌硬编码的值,但在这种情况下,他们帮了我很多。
我目前的代码如下:
private void Rotate(double value)
{
double sangle = value * 360 + 42;
vlb_outer.RenderTransform = new RotateTransform() { Angle = sangle, CenterX = 0, CenterY = 0 };
vlb_inner.RenderTransform = new RotateTransform() { Angle = -sangle, CenterX = 0, CenterY = 0 };
Value = (int)(value*360);
}
它获取值(从0到1)并将其乘以360(用于旋转)和一个用于修复起始位置的幻数。我不认为42是完美的,但周围的东西对我有用。
修改
此代码应该适合您
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
double sangle = circle.Percentage * 3.6 + 42;
vlb_outer.RenderTransform = new RotateTransform() { Angle = sangle, CenterX = 0, CenterY = 0 };
vlb_inner.RenderTransform = new RotateTransform() { Angle = -sangle, CenterX = 0, CenterY = 0 };
}
答案 1 :(得分:0)
我认为你只是搞砸了你的定位和利润。我没有你的圆圈控件,所以我只是使用一个静态的黄色圆圈来移动标签,并带有一个滑块用于演示:
<Grid>
<Slider x:Name="angleProvider" Minimum="0" Maximum="360" VerticalAlignment="Top" HorizontalAlignment="Center" MinWidth="100" Margin="10"/>
<Ellipse
Width="50" Height="50"
VerticalAlignment="Center" HorizontalAlignment="Center"
Fill="Yellow"/>
<Label
Content="{Binding ElementName=angleProvider,Path=Value}" ContentStringFormat="{}{0:##0'°'}"
RenderTransformOrigin="0.5,0.5"
Width="80" Height="80"
Padding="0"
VerticalAlignment="Center" HorizontalAlignment="Center"
VerticalContentAlignment="Top" HorizontalContentAlignment="Center">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding ElementName=angleProvider,Path=Value}"/>
<TranslateTransform/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</Grid>
所以基本上,将标签的中心放在与圆圈中心相同的位置,将标签内容放在中心位置,设置宽度和高度大于圆圈,使文字显示在外面,旋转标签它的中心。
注意我没有检查您实际需要的RotateTransform
以外的哪些变换。我认为可以从TransformGroup
删除所有其他内容。