【问题标题】:Fill Ellipse based on percentage根据百分比填充椭圆
【发布时间】:2014-03-14 06:40:08
【问题描述】:

我在 XAML 中创建了 Ellipse。

代码如下:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <Ellipse Width="400" Stroke="DodgerBlue" Height="400" StrokeThickness="75" Fill="Transparent">
   </Ellipse>
 </Grid>

假设椭圆是 100%,如果它的 20% 蓝色应该只填充到该位置,并且还在椭圆的中心(空白区域)显示百分比文本。

编辑

我已添加要在中心显示的文本。

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Ellipse Width="400" Stroke="DodgerBlue" Height="400" StrokeThickness="75" Fill="Transparent">
</Ellipse>
            <TextBlock VerticalAlignment="Center" 
                       HorizontalAlignment="Center" 
                       Text="20"
                       FontSize="125"/>
        </Grid>

编辑 2

这是我想要达到的效果:

这里是橙色,填充率为 20%。

【问题讨论】:

  • 您要填充蓝色边框,还是填充内部 - 当前透明 - 内容?
  • @Herdo 现在显示完全填充的蓝色,应该只填充 100 个中的 20 个(总椭圆),如果 80% 则填充 80% 椭圆,内部空应该为是
  • 您可以在 TextBlock.Text 属性中设置百分比(如果您使用例如 mvvm 设计模式,您可能会使用绑定),对于 Ellipse.StrokeThickness,请参阅 TextBlock.Text 属性(或绑定),并应用将百分比转换为StrokeThickness 的值的转换器。
  • @Herdo 这也很好,就像现在用蓝色填充一样,在此之上再填充一种颜色,比如红色,20% 或 80%
  • 然后在当前的上方创建第二个Ellipse,使其Fill 透明并将上述逻辑应用于此椭圆。

标签: c# wpf xaml windows-phone ellipse


【解决方案1】:

您可以在 Microsoft.Expression.Drawing 程序集中使用圆弧控制预设

它具有诸如 StartAngle 和 EndAngle 之类的属性,可以很好地进行相应的操作。

 <es:Arc x:Name="arc" ArcThickness="3" ArcThicknessUnit="Pixel" EndAngle="360" Fill="Black" Height="270" Canvas.Left="101.94" Stroke="Black" StartAngle="0" UseLayoutRounding="False" Width="269.941" Canvas.Top="12" />

现在您可以使用此控件做的是:只需取两条相似的弧线,一条重叠另一条, 用蓝色为下面的一个(第一弧)着色,并为红色弧(第二弧)赋予开始和结束角度属性,这将使您的布局看起来像设计二中提到的方式。

原始用法:

<Canvas x:Name="canvas1" Margin="0,10,0,0" Height="300" Width="480" HorizontalAlignment="Center">
<es:Arc x:Name="arc" ArcThickness="3" ArcThicknessUnit="Pixel" Fill="Black" Height="100" Canvas.Left="0" Stroke="Blue" UseLayoutRounding="False" Width="100" Canvas.Top="0"/>
</Canvas>
<es:Arc x:Name="arc" ArcThickness="3" EndAngle="120" StartAngle="0" ArcThicknessUnit="Pixel" Fill="Blue" Height="100" Canvas.Left="0" Stroke="Blue" UseLayoutRounding="False" Width="100" Canvas.Top="0"/>
</Canvas>

也检查this 链接

【讨论】:

  • 你能详细说明一下,什么是es?以及我的布局应该是什么样子?
  • es 只是 xaml 页面顶部的引用:xmlns:es="clr-namespace:Microsoft.Expression.Shapes;assembly=Microsoft.Expression.Drawing"
  • 你能告诉我我的网格是什么样子吗?我很困惑,您的解决方案似乎有效
  • 取一个画布控件,并根据角度值将两条相同尺寸和相同位置坐标的弧放入其中,下面的一个完全填充,上面的一个部分填充。
  • 我很抱歉阿曼,因为我是 WP8 的新手,我不知道如何做到这一点,以及如何使用或创建画布控件
【解决方案2】:

用户控件版本由两部分组成:XAML + 代码隐藏。 XAML 部分:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Project.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d"
d:DesignHeight="40"
d:DesignWidth="40">


<Grid Width="40" Height="40">
    <Ellipse StrokeThickness="3" Stroke="#FF89CE25"/>
    <Path Stroke="Red" StrokeThickness="2" x:Name="arcPath">
        <Path.Data>
            <PathGeometry>
                <PathFigure StartPoint="20,1">
                    <ArcSegment x:Name="myArc" SweepDirection="Clockwise" IsLargeArc="True" Point="20,1"/>
                </PathFigure>
            </PathGeometry>
        </Path.Data>
    </Path>
</Grid>

代码隐藏文件(短版,没有绒毛):

public sealed partial class MyCustomControl : UserControl
{


public double ProgressValue
{
    get { return (double)GetValue(ProgressValueProperty); }
    set { SetValue(ProgressValueProperty, value); }
}

// Using a DependencyProperty as the backing store for ProgressValue.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ProgressValueProperty =
    DependencyProperty.Register("ProgressValue", typeof(double), typeof(MyCustomControl), new PropertyMetadata(0.0, OnProgressValueChanged));

private static void OnProgressValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    //throw new NotImplementedException();
    MyCustomControl circularProgressBar = d as MyCustomControl;
    if (circularProgressBar != null)
    {
        double r = 19;
        double x0 = 20;
        double y0 = 20;
        circularProgressBar.myArc.Size = new Size(19, 19);
        double angle = 90 - (double)e.NewValue / 100 * 360;
        double radAngle = angle * (PI / 180);
        double x = x0 + r * Cos(radAngle);
        double y = y0 - r * Sin(radAngle);

        if (circularProgressBar.myArc != null)
        {
            circularProgressBar.myArc.IsLargeArc = ((double)e.NewValue >= 50);
            circularProgressBar.myArc.Point = new Point(x, y);
        }
    }
}

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

}

现在,您可以将 CustomControl 放入 XAML 中的任何位置,并将 ProgressValue 属性绑定到相应的数据源。圆弧会自行重绘,并根据值(0-100 之间的值)按比例填充椭圆形状。

【讨论】:

    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 2021-01-21
    • 2017-01-23
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    相关资源
    最近更新 更多