效果图:
主要代码xaml:
- <UserControl x:Class="INSControls._01Conning.Steer.ConningSpeedBar"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:ec="http://schemas.microsoft.com/expression/2010/controls"
- xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
- mc:Ignorable="d"
- d:DesignHeight="300"
- d:DesignWidth="80" Focusable="False" FocusVisualStyle="{x:Null}" Loaded="UserControl_Loaded">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="40" />
- </Grid.RowDefinitions>
- <Label HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Content="{Binding Title, RelativeSource={RelativeSource AncestorType=UserControl}}"
- Foreground="{Binding LabelColor, RelativeSource={RelativeSource AncestorType=UserControl} }"
- FontFamily="微软雅黑"></Label>
- <Label HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Margin="0,0,0,5"
- Foreground="#cc8800"
- FontFamily="微软雅黑"
- Content="LOG2"
- Grid.Row="1" />
- <Border Width="80"
- HorizontalAlignment="Left"
- Grid.Row="2"
- Background="#24325f">
- <Grid Margin="1,14,0,14"
- x:Name="mainGrid">
- <!--具体的值填充的柱状图形-->
- <Grid x:Name="graphicGrid"
- Height="10"
- VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
-
-
- <Path Data="M40,0 L80,40 L0,40 z"
- Fill="#cc0663c2" Stretch="Fill" x:Name="path" />
-
- <Border Grid.Row="1"
- Background="#cc0663c2" />
- <Grid.RenderTransform>
- <RotateTransform Angle="0" x:Name="polygonRotateAngel" />
- </Grid.RenderTransform>
- </Grid>
- <!--短刻度-->
- <ec:PathListBox Background="Transparent"
- x:Name="shortTicks"
- ItemsSource="{Binding ShortTicks,RelativeSource={RelativeSource AncestorType=UserControl}}"
- Focusable="False"
- FocusVisualStyle="{x:Null}">
- <ec:PathListBox.ItemTemplate>
- <DataTemplate>
- <Rectangle Width="1"
- Height="48"
- Margin="0,0,0,49"
- Fill="#b5b5b5"
- Focusable="False"
- FocusVisualStyle="{x:Null}" />
- <!--<Border Width="1"
- Height="48"
- Background="#b5b5b5"
- UseLayoutRounding="True"
- Margin="0,0,0,49" />-->
- </DataTemplate>
- </ec:PathListBox.ItemTemplate>
- <ec:PathListBox.LayoutPaths>
- <ec:LayoutPath Distribution="Even"
- Orientation="OrientToPath"
- SourceElement="{Binding ElementName=ShortTickPath}" >
-
- </ec:LayoutPath>
- </ec:PathListBox.LayoutPaths>
- </ec:PathListBox>
- <!-- 长刻度 -->
- <ec:PathListBox x:Name="LongTick"
- IsHitTestVisible="False"
- ItemsSource="{Binding LongTicks, RelativeSource={RelativeSource AncestorType=UserControl}}"
- Focusable="False"
- FocusVisualStyle="{x:Null}" >
- <ec:PathListBox.ItemTemplate>
- <DataTemplate>
- <Rectangle Width="48"
- Height="3"
- Margin="48,0,0,0"
- Fill="White"
- Focusable="False"
- FocusVisualStyle="{x:Null}" />
- <!--<Border Width="3"
- Height="48"
- Background="White"
- SnapsToDevicePixels="True"
- UseLayoutRounding="True"
- Margin="0,0,0,49">
- </Border>-->
- </DataTemplate>
- </ec:PathListBox.ItemTemplate>
- <ec:PathListBox.LayoutPaths>
- <ec:LayoutPath Distribution="Even"
- Orientation="None"
- SourceElement="{Binding ElementName=LongTickPath}" />
- </ec:PathListBox.LayoutPaths>
- </ec:PathListBox>
-
- <!-- 刻度上显示的数字 -->
- <ec:PathListBox IsHitTestVisible="False"
- ItemsSource="{Binding TickMarks,RelativeSource={RelativeSource AncestorType=UserControl}}">
-
-
- <ec:PathListBox.ItemTemplate>
- <DataTemplate>
- <TextBlock x:Name="tb" HorizontalAlignment="Left" Foreground="White"
- Text="{Binding}" RenderTransformOrigin="0,0" Margin="0,50,0,0">
- <TextBlock.RenderTransform>
- <RotateTransform Angle="-90"/>
- </TextBlock.RenderTransform>
- </TextBlock>
- </DataTemplate>
- </ec:PathListBox.ItemTemplate>
- <ec:PathListBox.LayoutPaths>
- <ec:LayoutPath Distribution="Even"
- Orientation="OrientToPath"
- SourceElement="{Binding ElementName=NumberPath}" />
- </ec:PathListBox.LayoutPaths>
- </ec:PathListBox>
-
- <Path x:Name="LongTickPath"
- Data="M0,0 v1"
- VerticalAlignment="Top"
- HorizontalAlignment="Right"
- Stretch="Fill" Fill="Red" Stroke="Red" StrokeThickness="2"
- Grid.RowSpan="2"
- Margin="0,0"
- Focusable="False"
- FocusVisualStyle="{x:Null}" />
- <Path x:Name="ShortTickPath"
- Data="M0,0 V1"
- VerticalAlignment="Top"
- HorizontalAlignment="Left"
- Stretch="Fill"
- Grid.RowSpan="2"
- Margin="0,0"
- Focusable="False"
- FocusVisualStyle="{x:Null}" />
-
- <Path x:Name="NumberPath"
- Data="M0,0 V1"
- Margin="45,0,0,0"
- VerticalAlignment="Top"
- HorizontalAlignment="Center"
- Stretch="Fill"
- Grid.RowSpan="2"
- Focusable="False"
- FocusVisualStyle="{x:Null}" Stroke="Yellow" StrokeThickness="1"/>
-
- </Grid>
- </Border>
-
- <StackPanel Grid.Row="3"
- Orientation="Horizontal">
- <TextBox Width="90"
- Height="35"
- IsReadOnly="True"
- Foreground="{Binding TextboxColor,RelativeSource={RelativeSource AncestorType=UserControl}}"
- VerticalAlignment="Center"
- Text="{ Binding CurrentValue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Control}}" />
- <Label VerticalAlignment="Center"
- Content="km"
- Foreground="{Binding LabelColor, RelativeSource={RelativeSource AncestorType=UserControl}}"></Label>
- </StackPanel>
-
- </Grid>
- </UserControl>
.cs文件:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
-
- namespace INSControls._01Conning.Steer
- {
- /// <summary>
- /// ConningSpeedBar.xaml 的交互逻辑
- /// </summary>
- public partial class ConningSpeedBar : UserControl
- {
- public ConningSpeedBar()
- {
- InitializeComponent();
- }
-
- public List<string> TickMarks
- {
- get { return (List<string>)GetValue(TickMarksProperty); }
- set { SetValue(TickMarksProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for TickMarks. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty TickMarksProperty =
- DependencyProperty.Register("TickMarks", typeof(List<string>), typeof(ConningSpeedBar), new PropertyMetadata(null));
-
-
-
-
- public List<object> LongTicks
- {
- get { return (List<object>)GetValue(LongTicksProperty); }
- set { SetValue(LongTicksProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for LongTicks. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty LongTicksProperty =
- DependencyProperty.Register("LongTicks", typeof(List<object>), typeof(ConningSpeedBar), new PropertyMetadata(null));
-
-
-
- public List<object> ShortTicks
- {
- get { return (List<object>)GetValue(ShortTicksProperty); }
- set { SetValue(ShortTicksProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for ShortTicks. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ShortTicksProperty =
- DependencyProperty.Register("ShortTicks", typeof(List<object>), typeof(ConningSpeedBar), new PropertyMetadata(null));
-
-
-
-
- public double CurrentValue
- {
- get { return (double)GetValue(CurrentValueProperty); }
- set { SetValue(CurrentValueProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for CurrentValue. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CurrentValueProperty =
- DependencyProperty.Register("CurrentValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(0.0, CurrentValueChangeCallback));
-
- private static void CurrentValueChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ConningSpeedBar c = d as ConningSpeedBar;
- UpdateUICurrentvalue((double)e.NewValue, c);
- }
-
- private static void UpdateUICurrentvalue(double currentValue, ConningSpeedBar c)
- {
- if (c.mainGrid.ActualHeight==0)
- {
- return;
- }
- if (currentValue > 0)
- {
- c.polygonRotateAngel.Angle = 0;
- double totalValue = c.MaxValue - c.MinValue;
- //计算显示图形位置
- double top = (c.MaxValue - currentValue) * c.mainGrid.ActualHeight / totalValue;
- //计算显示图形大小
- double height = currentValue * c.mainGrid.ActualHeight / totalValue;
- c.graphicGrid.Margin = new Thickness(0, top, 0, 0);
- if (height > 40)
- {
- c.graphicGrid.Height = height;
- }
- else
- {
- c.graphicGrid.Height = c.path.Height = height;
- }
-
- }
- else
- {
- c.polygonRotateAngel.Angle = 180;
- double totalValue = c.MaxValue - c.MinValue;
- //计算显示图形位置
- double top = (c.MaxValue) * c.mainGrid.ActualHeight / totalValue;
- //计算显示图形大小
- double height = -currentValue * c.mainGrid.ActualHeight / totalValue;
- c.graphicGrid.Margin = new Thickness(0, top, 0, 0);
- if (height > 40)
- {
- c.graphicGrid.Height = height;
- }
- else
- {
- c.graphicGrid.Height = c.path.Height = height;
- }
- }
-
- }
-
- public SolidColorBrush LabelColor
- {
- get { return (SolidColorBrush)GetValue(LabelColorProperty); }
- set { SetValue(LabelColorProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for LabelColor. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty LabelColorProperty =
- DependencyProperty.Register("LabelColor", typeof(SolidColorBrush), typeof(ConningSpeedBar), new PropertyMetadata(Brushes.Black));
-
-
-
- public SolidColorBrush TextboxColor
- {
- get { return (SolidColorBrush)GetValue(TextboxColorProperty); }
- set { SetValue(TextboxColorProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for TextboxColor. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty TextboxColorProperty =
- DependencyProperty.Register("TextboxColor", typeof(SolidColorBrush), typeof(ConningSpeedBar), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(214, 214, 214))));
-
-
-
-
- public string Title
- {
- get { return (string)GetValue(TitleProperty); }
- set { SetValue(TitleProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty TitleProperty =
- DependencyProperty.Register("Title", typeof(string), typeof(ConningSpeedBar), new PropertyMetadata(""));
-
-
-
-
- public double MaxValue
- {
- get { return (double)GetValue(MaxValueProperty); }
- set { SetValue(MaxValueProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for MaxValue. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty MaxValueProperty =
- DependencyProperty.Register("MaxValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(30d));
-
-
-
-
- public double MinValue
- {
- get { return (double)GetValue(MinValueProperty); }
- set { SetValue(MinValueProperty, value); }
- }
-
- // Using a DependencyProperty as the backing store for MinValue. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty MinValueProperty =
- DependencyProperty.Register("MinValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(-10d));
-
- private void UserControl_Loaded(object sender, RoutedEventArgs e)
- {
- //短刻度
- List<object> shortticks = new List<object>();
- for (int i = 0; i < 50; i++)
- {
- shortticks.Add(new object());
- }
- ShortTicks = shortticks;
- //显示刻度文字
- List<string> numbers = new List<string>();
- //长刻度
- List<object> longticks = new List<object>();
- for (int i = 0; i < 5; i++)
- {
- //计算长度信息,等比例地减去间隔值
- string tickInfo = (MaxValue - i * (MaxValue - MinValue) / 4).ToString();
- numbers.Add(tickInfo+new string('&',i+1));
- longticks.Add(new object());
- }
- LongTicks = longticks;
- TickMarks = numbers;
- UpdateUICurrentvalue(CurrentValue, this) ;
- }
-
- }
- }
源码地址:
https://files.cnblogs.com/files/chlm/%E5%88%BB%E5%BA%A6%E7%BA%BF.rar