将进度条扭转 90 度

发布于 2024-12-12 04:02:48 字数 100 浏览 0 评论 0原文

我正在做一个能量流的应用程序。我想使用进度条显示能量流动。我需要在某个时刻转动进度条并且仍然持续流动。有没有办法将进度条上的点旋转 90 度?例如L形。

知道如何去做吗?

I am doing an application for energy flow. I would like to show energy flowing using progress bars. I would need to turn the progress bars at some point and still flow continously. Is there a way to turn a point on the progress bar by 90 degrees? For example an L shape.

Any idea how to go about it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甲如呢乙后呢 2024-12-19 04:02:48

好的,我完成了。所以编辑这个页面。我想这就是你需要的。

创建一个新的 WPF 项目并对其进行编辑。

Xaml 代码 MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <my:PointConverter x:Key="PointConverter" />
        <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(RangeBase.Value)" Storyboard.TargetName="progress">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="100"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <ProgressBar Name="progress" Width="200" Height="200" Value="100">
            <ProgressBar.Template>
                <ControlTemplate TargetType="{x:Type ProgressBar}">
                    <Rectangle Fill="#FF1FFF00"/>
                </ControlTemplate>
            </ProgressBar.Template>
            <ProgressBar.Clip>
                <PathGeometry>
                    <PathFigure StartPoint="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=1}">
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=2}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=3}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=4}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=5}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=6}"/>
                    </PathFigure>
                </PathGeometry>
            </ProgressBar.Clip>
        </ProgressBar>
    </Grid>
</Window>

将此类添加到 MainWindow.xaml.cs 文件中:

public class PointConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            double val = (double)value;
            int num = int.Parse("" + parameter);
            if (num == 1)
            {
                if (val < 50) return new Point(200 - val * 4, 200);
                else return new Point(0, 200 - (val - 50) * 4);
            }
            else if (num == 2)
            {
                if (val < 50) return new Point(200 - val * 4, 200);
                else return new Point(0, 200);
            }
            else if (num == 3)
            {
                return new Point(200, 200);
            }
            else if (num == 4)
            {
                return new Point(200, 100);
            }
            else if (num == 5)
            {
                if (val < 25) return new Point(200 - val * 4, 100);
                else return new Point(100, 100);
            }
            else if (num == 6)
            {
                if (val < 25) return new Point(200 - val * 4, 100);
                else if (val < 75) return new Point(100, 100);
                else return new Point(100, 200 - (val - 50) * 4);
            }
        }
        catch { }

        return new Point();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Ok, i finished it. so edit this page. i guess this is you need.

Create a New WPF Project and edit it.

Xaml code MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <my:PointConverter x:Key="PointConverter" />
        <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(RangeBase.Value)" Storyboard.TargetName="progress">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="100"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <ProgressBar Name="progress" Width="200" Height="200" Value="100">
            <ProgressBar.Template>
                <ControlTemplate TargetType="{x:Type ProgressBar}">
                    <Rectangle Fill="#FF1FFF00"/>
                </ControlTemplate>
            </ProgressBar.Template>
            <ProgressBar.Clip>
                <PathGeometry>
                    <PathFigure StartPoint="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=1}">
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=2}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=3}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=4}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=5}"/>
                        <LineSegment Point="{Binding ElementName=progress, Path=Value, Converter={StaticResource PointConverter}, ConverterParameter=6}"/>
                    </PathFigure>
                </PathGeometry>
            </ProgressBar.Clip>
        </ProgressBar>
    </Grid>
</Window>

Add this class into your MainWindow.xaml.cs file:

public class PointConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            double val = (double)value;
            int num = int.Parse("" + parameter);
            if (num == 1)
            {
                if (val < 50) return new Point(200 - val * 4, 200);
                else return new Point(0, 200 - (val - 50) * 4);
            }
            else if (num == 2)
            {
                if (val < 50) return new Point(200 - val * 4, 200);
                else return new Point(0, 200);
            }
            else if (num == 3)
            {
                return new Point(200, 200);
            }
            else if (num == 4)
            {
                return new Point(200, 100);
            }
            else if (num == 5)
            {
                if (val < 25) return new Point(200 - val * 4, 100);
                else return new Point(100, 100);
            }
            else if (num == 6)
            {
                if (val < 25) return new Point(200 - val * 4, 100);
                else if (val < 75) return new Point(100, 100);
                else return new Point(100, 200 - (val - 50) * 4);
            }
        }
        catch { }

        return new Point();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
眼眸印温柔 2024-12-19 04:02:48

我用混合创建了一个简单的动画:一个 L 形路径和一个 DoubleKeyFrame 动画,它改变了 GradientStop 偏移量,使 L 看起来像是被填充了。

通过一些额外的努力,您还可以旋转画笔,使其路径跟随弯曲,从而获得更好的填充效果。动画在框架加载事件上触发,并出于演示原因永远重复。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApplication.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">

  <Window.Resources>
    <Storyboard x:Key="Storyboard1">
      <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.StartPoint)" Storyboard.TargetName="ColorFill">
        <EasingPointKeyFrame KeyTime="0" Value="0.025,0.954"/>
      </PointAnimationUsingKeyFrames>
      <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.EndPoint)" Storyboard.TargetName="ColorFill">
        <EasingPointKeyFrame KeyTime="0" Value="0.97,0.004"/>
      </PointAnimationUsingKeyFrames>
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ColorFill">
        <EasingColorKeyFrame KeyTime="0" Value="White"/>
      </ColorAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="ColorFill">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0.046"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.11"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.184"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0.251"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.343"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0.445"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.542"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="0.65"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="0.798"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.897"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="0.969"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1"/>
      </DoubleAnimationUsingKeyFrames>
    </Storyboard>
  </Window.Resources>
  <Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
      <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
    </EventTrigger>
  </Window.Triggers>

  <Grid x:Name="LayoutRoot" Margin="0,0,-195.6,-162">
    <Path Data="M105.8,91" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="1" Margin="105.8,91,0,0" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" Width="1"/>
    <Path x:Name="ColorFill" Data="M187.2,0.5 L234.4,0.5 C242.07676,0.5 248.3,6.7232418 248.3,14.399999 L248.3,187.2 248.3,234.39999 C248.3,234.87979 248.2757,235.35391 248.22824,235.82118 248.18079,236.28847 248.11018,236.7489 248.0176,237.20132 247.92503,237.65376 247.81046,238.09818 247.67509,238.53343 247.53971,238.96867 247.38351,239.39476 247.20767,239.8105 247.03183,240.22624 246.83633,240.63165 246.62235,241.02556 246.40836,241.41946 246.1759,241.80188 245.9261,242.17162 245.67631,242.54137 245.40919,242.89844 245.12592,243.24168 244.84264,243.58493 244.54321,243.91435
244.22878,244.22878 243.91436,244.54321 243.58494,244.84264 243.24169,245.12592 242.89845,245.40919 242.54137,245.6763 242.17162,245.9261 241.80188,246.17589 241.41947,246.40836 241.02557,246.62234 240.63166,246.83633 240.22625,247.03183 239.81051,247.20767 239.39477,247.38351 238.96869,247.5397 238.53343,247.67508 238.09818,247.81046 237.65376,247.92502 237.20134,248.01761 236.74891,248.11018 236.28847,248.18079 235.82119,248.22824 235.35392,248.2757
234.8798,248.3 234.4,248.3 L187.2,248.3 14.400009,248.3 C6.7232513,248.3 0.5,242.07675 0.5,234.39999 L0.5,187.2 C0.5,179.52324 6.7232513,173.3 14.400009,173.3 L173.3,173.3 173.3,14.399999 C173.3,6.7232418 179.52324,0.5 187.2,0.5 z" HorizontalAlignment="Left" Margin="-5.4,267.4,0,89.8" RenderTransformOrigin="0.847266882902349,0.499999993867046" Stretch="Fill" Stroke="Black" Width="248.8">
      <Path.Fill>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
          <GradientStop Color="Green" Offset="0"/>
          <GradientStop Color="White" Offset="1"/>
        </LinearGradientBrush>
      </Path.Fill>

      <Path.RenderTransform>
        <TransformGroup>
          <ScaleTransform/>
          <SkewTransform/>
          <RotateTransform Angle="90"/>
          <TranslateTransform/>
        </TransformGroup>
      </Path.RenderTransform>
    </Path>
  </Grid>
</Window>

I have created a simple animation with blend: An L-shaped Path and a DoubleKeyFrame animation which changes the GradientStop Offsets so the L looks like it gets filled.

With some additional effort you could also Rotate the Brush so its path is following the bend abd you get a nicer fill effect. The animation triggers on the framework Loaded Event and repeats forever for demo reasons.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApplication.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">

  <Window.Resources>
    <Storyboard x:Key="Storyboard1">
      <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.StartPoint)" Storyboard.TargetName="ColorFill">
        <EasingPointKeyFrame KeyTime="0" Value="0.025,0.954"/>
      </PointAnimationUsingKeyFrames>
      <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.EndPoint)" Storyboard.TargetName="ColorFill">
        <EasingPointKeyFrame KeyTime="0" Value="0.97,0.004"/>
      </PointAnimationUsingKeyFrames>
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ColorFill">
        <EasingColorKeyFrame KeyTime="0" Value="White"/>
      </ColorAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="ColorFill">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0.046"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.11"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.184"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0.251"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.343"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0.445"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.542"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="0.65"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="0.798"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.897"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="0.969"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1"/>
      </DoubleAnimationUsingKeyFrames>
    </Storyboard>
  </Window.Resources>
  <Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
      <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
    </EventTrigger>
  </Window.Triggers>

  <Grid x:Name="LayoutRoot" Margin="0,0,-195.6,-162">
    <Path Data="M105.8,91" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="1" Margin="105.8,91,0,0" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" Width="1"/>
    <Path x:Name="ColorFill" Data="M187.2,0.5 L234.4,0.5 C242.07676,0.5 248.3,6.7232418 248.3,14.399999 L248.3,187.2 248.3,234.39999 C248.3,234.87979 248.2757,235.35391 248.22824,235.82118 248.18079,236.28847 248.11018,236.7489 248.0176,237.20132 247.92503,237.65376 247.81046,238.09818 247.67509,238.53343 247.53971,238.96867 247.38351,239.39476 247.20767,239.8105 247.03183,240.22624 246.83633,240.63165 246.62235,241.02556 246.40836,241.41946 246.1759,241.80188 245.9261,242.17162 245.67631,242.54137 245.40919,242.89844 245.12592,243.24168 244.84264,243.58493 244.54321,243.91435
244.22878,244.22878 243.91436,244.54321 243.58494,244.84264 243.24169,245.12592 242.89845,245.40919 242.54137,245.6763 242.17162,245.9261 241.80188,246.17589 241.41947,246.40836 241.02557,246.62234 240.63166,246.83633 240.22625,247.03183 239.81051,247.20767 239.39477,247.38351 238.96869,247.5397 238.53343,247.67508 238.09818,247.81046 237.65376,247.92502 237.20134,248.01761 236.74891,248.11018 236.28847,248.18079 235.82119,248.22824 235.35392,248.2757
234.8798,248.3 234.4,248.3 L187.2,248.3 14.400009,248.3 C6.7232513,248.3 0.5,242.07675 0.5,234.39999 L0.5,187.2 C0.5,179.52324 6.7232513,173.3 14.400009,173.3 L173.3,173.3 173.3,14.399999 C173.3,6.7232418 179.52324,0.5 187.2,0.5 z" HorizontalAlignment="Left" Margin="-5.4,267.4,0,89.8" RenderTransformOrigin="0.847266882902349,0.499999993867046" Stretch="Fill" Stroke="Black" Width="248.8">
      <Path.Fill>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
          <GradientStop Color="Green" Offset="0"/>
          <GradientStop Color="White" Offset="1"/>
        </LinearGradientBrush>
      </Path.Fill>

      <Path.RenderTransform>
        <TransformGroup>
          <ScaleTransform/>
          <SkewTransform/>
          <RotateTransform Angle="90"/>
          <TranslateTransform/>
        </TransformGroup>
      </Path.RenderTransform>
    </Path>
  </Grid>
</Window>
天冷不及心凉 2024-12-19 04:02:48

这可以使用 VisualBrush 来完成。

可能需要一段时间才能正确,但我会按如下方式处理:

  1. 添加一个 ProgressBar,根据需要连接

  2. 使用 VisualBrush,引用 ProgressBar 作为其 Visual,使用 Path 设置 基于不透明蒙版足够大覆盖 ProgressBar 的左半部分(使用渐变混合或 -45 度对角线右侧边缘),以绘制“L 形条”的水平部分

  3. 使用第二个 VisualBrush,同时引用 ProgressBar 作为其 Visual,设置一个基于 Path 的不透明蒙版,该蒙版足够大以覆盖 ProgressBar 的右半部分(渐变混合或 45 度对角线左手边),绘制“L 形条”的垂直部分

This can be done using a VisualBrush.

It may take a while to get it right, but I would approach it as follows:

  1. Add a single ProgressBar, hooked up as required

  2. Use a VisualBrush, referencing the ProgressBar as its Visual, set up with a Path based opacity mask big enough to cover the left half of the ProgressBar (with a gradient blended or -45 degree diagonal right hand edge), to draw the horizontal part of the 'L-shaped bar'

  3. Use a second VisualBrush, also referencing the ProgressBar as its Visual, set up with a Path based opacity mask big enough to cover the right half of the ProgressBar (with a gradient blended or 45 degree diagonal left hand edge), to draw the vertical part of the 'L-shaped bar'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文