#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 .
Может потребоваться некоторое время, чтобы сделать это правильно, но я бы подошел к этому следующим образом:
-
Добавьте один
ProgressBar
, подключенный по мере необходимости -
Используйте a
VisualBrush
, ссылаясь наProgressBar
as itsVisual
, настроенный сPath
маской непрозрачности на основе, достаточно большой, чтобы покрыть левую половинуProgressBar
(со смешанным градиентом или -45 градусов по диагонали правого края), чтобы нарисовать горизонтальную часть «L-образной полосы» -
Используйте вторую
VisualBrush
, также ссылающуюся наProgressBar
as itsVisual
, настройку сPath
маской непрозрачности, достаточно большой, чтобы покрыть правую половину панели прогресса (со смешанным градиентом или левым краем по диагонали 45 градусов), чтобы нарисовать вертикальную часть «L-образной панели»
Комментарии:
1. Будет ли поток в progressbar непрерывным?
2. Да, это было бы. Поток в соединении буквы «L» может быть изменен в зависимости от того, как вы сопоставляете и / или смешиваете два элемента управления на основе VisualBrush.