Поворот панели прогресса на 90 градусов

#c# #wpf #progress-bar

#c# #wpf #индикатор выполнения

Вопрос:

Я делаю приложение для потока энергии. Я хотел бы показать поток энергии с помощью индикаторов выполнения. В какой-то момент мне нужно было бы повернуть индикаторы выполнения и продолжать работать непрерывно. Есть ли способ повернуть точку на индикаторе выполнения на 90 градусов? Например, L-образная форма.

Есть идеи, как это сделать?

Комментарии:

1. Вы должны использовать WPF с пользовательской анимацией или просто Windows Forms с пользовательским рисунком. Это может потребовать немного работы для настройки, но не должно быть так много работы.

2. Ооо, есть идеи, как это сделать? Извините, но я довольно новичок в этом..

Ответ №1:

Хорошо, я закончил. так что отредактируйте эту страницу. я думаю, это вам нужно.

Создайте новый проект 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();
    }
}
  

Комментарии:

1. Спасибо! Однако он заполняется снизу вверх. Есть ли способ заполнить ее справа налево, а затем вверх? Способ, которым обычно течет энергия

2. @ScottParker ваши идеи можно реализовать, но для этого нужно использовать IValueConverter , даже нужно модифицировать ControlTemplate

3. Спасибо, отличный. И последнее, как мне изменить его длину или ширину в соответствии с моими потребностями?

4. @ScottParker необходимо изменить схему, которая заменит клип на ProgressBar. Шаблон. наконец, вам понадобится окно просмотра.

Ответ №2:

Я создал простую анимацию с помощью blend: L-образный контур и анимацию двойного ключевого кадра, которая изменяет смещения GradientStop, чтобы L выглядел так, как будто он заполняется.

Приложив некоторые дополнительные усилия, вы также можете повернуть кисть так, чтобы ее траектория следовала изгибу abd, и вы получите более приятный эффект заливки. Анимация запускается при событии загрузки фреймворка и повторяется вечно по демонстрационным причинам.

 <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.91435amp;#xa;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.2757amp;#xa;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>
  

Комментарии:

1. Спасибо, но это не то, что я искал.

Ответ №3:

Это можно сделать с помощью VisualBrush .

Может потребоваться некоторое время, чтобы сделать это правильно, но я бы подошел к этому следующим образом:

  1. Добавьте один ProgressBar , подключенный по мере необходимости

  2. Используйте a VisualBrush , ссылаясь на ProgressBar as its Visual , настроенный с Path маской непрозрачности на основе, достаточно большой, чтобы покрыть левую половину ProgressBar (со смешанным градиентом или -45 градусов по диагонали правого края), чтобы нарисовать горизонтальную часть «L-образной полосы»

  3. Используйте вторую VisualBrush , также ссылающуюся на ProgressBar as its Visual , настройку с Path маской непрозрачности, достаточно большой, чтобы покрыть правую половину панели прогресса (со смешанным градиентом или левым краем по диагонали 45 градусов), чтобы нарисовать вертикальную часть «L-образной панели»

Комментарии:

1. Будет ли поток в progressbar непрерывным?

2. Да, это было бы. Поток в соединении буквы «L» может быть изменен в зависимости от того, как вы сопоставляете и / или смешиваете два элемента управления на основе VisualBrush.