当前位置:   article > 正文

wpf自定义带刻度的柱状图控件

wpf 柱状图

效果图:

主要代码xaml:

  1. <UserControl x:Class="INSControls._01Conning.Steer.ConningSpeedBar"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:ec="http://schemas.microsoft.com/expression/2010/controls"
  7. xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
  8. mc:Ignorable="d"
  9. d:DesignHeight="300"
  10. d:DesignWidth="80" Focusable="False" FocusVisualStyle="{x:Null}" Loaded="UserControl_Loaded">
  11. <Grid>
  12. <Grid.RowDefinitions>
  13. <RowDefinition Height="Auto" />
  14. <RowDefinition Height="Auto" />
  15. <RowDefinition Height="*" />
  16. <RowDefinition Height="40" />
  17. </Grid.RowDefinitions>
  18. <Label HorizontalAlignment="Left"
  19. VerticalAlignment="Center"
  20. Content="{Binding Title, RelativeSource={RelativeSource AncestorType=UserControl}}"
  21. Foreground="{Binding LabelColor, RelativeSource={RelativeSource AncestorType=UserControl} }"
  22. FontFamily="微软雅黑"></Label>
  23. <Label HorizontalAlignment="Left"
  24. VerticalAlignment="Center"
  25. Margin="0,0,0,5"
  26. Foreground="#cc8800"
  27. FontFamily="微软雅黑"
  28. Content="LOG2"
  29. Grid.Row="1" />
  30. <Border Width="80"
  31. HorizontalAlignment="Left"
  32. Grid.Row="2"
  33. Background="#24325f">
  34. <Grid Margin="1,14,0,14"
  35. x:Name="mainGrid">
  36. <!--具体的值填充的柱状图形-->
  37. <Grid x:Name="graphicGrid"
  38. Height="10"
  39. VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
  40. <Grid.RowDefinitions>
  41. <RowDefinition Height="Auto" />
  42. <RowDefinition Height="*" />
  43. </Grid.RowDefinitions>
  44. <Path Data="M40,0 L80,40 L0,40 z"
  45. Fill="#cc0663c2" Stretch="Fill" x:Name="path" />
  46. <Border Grid.Row="1"
  47. Background="#cc0663c2" />
  48. <Grid.RenderTransform>
  49. <RotateTransform Angle="0" x:Name="polygonRotateAngel" />
  50. </Grid.RenderTransform>
  51. </Grid>
  52. <!--短刻度-->
  53. <ec:PathListBox Background="Transparent"
  54. x:Name="shortTicks"
  55. ItemsSource="{Binding ShortTicks,RelativeSource={RelativeSource AncestorType=UserControl}}"
  56. Focusable="False"
  57. FocusVisualStyle="{x:Null}">
  58. <ec:PathListBox.ItemTemplate>
  59. <DataTemplate>
  60. <Rectangle Width="1"
  61. Height="48"
  62. Margin="0,0,0,49"
  63. Fill="#b5b5b5"
  64. Focusable="False"
  65. FocusVisualStyle="{x:Null}" />
  66. <!--<Border Width="1"
  67. Height="48"
  68. Background="#b5b5b5"
  69. UseLayoutRounding="True"
  70. Margin="0,0,0,49" />-->
  71. </DataTemplate>
  72. </ec:PathListBox.ItemTemplate>
  73. <ec:PathListBox.LayoutPaths>
  74. <ec:LayoutPath Distribution="Even"
  75. Orientation="OrientToPath"
  76. SourceElement="{Binding ElementName=ShortTickPath}" >
  77. </ec:LayoutPath>
  78. </ec:PathListBox.LayoutPaths>
  79. </ec:PathListBox>
  80. <!-- 长刻度 -->
  81. <ec:PathListBox x:Name="LongTick"
  82. IsHitTestVisible="False"
  83. ItemsSource="{Binding LongTicks, RelativeSource={RelativeSource AncestorType=UserControl}}"
  84. Focusable="False"
  85. FocusVisualStyle="{x:Null}" >
  86. <ec:PathListBox.ItemTemplate>
  87. <DataTemplate>
  88. <Rectangle Width="48"
  89. Height="3"
  90. Margin="48,0,0,0"
  91. Fill="White"
  92. Focusable="False"
  93. FocusVisualStyle="{x:Null}" />
  94. <!--<Border Width="3"
  95. Height="48"
  96. Background="White"
  97. SnapsToDevicePixels="True"
  98. UseLayoutRounding="True"
  99. Margin="0,0,0,49">
  100. </Border>-->
  101. </DataTemplate>
  102. </ec:PathListBox.ItemTemplate>
  103. <ec:PathListBox.LayoutPaths>
  104. <ec:LayoutPath Distribution="Even"
  105. Orientation="None"
  106. SourceElement="{Binding ElementName=LongTickPath}" />
  107. </ec:PathListBox.LayoutPaths>
  108. </ec:PathListBox>
  109. <!-- 刻度上显示的数字 -->
  110. <ec:PathListBox IsHitTestVisible="False"
  111. ItemsSource="{Binding TickMarks,RelativeSource={RelativeSource AncestorType=UserControl}}">
  112. <ec:PathListBox.ItemTemplate>
  113. <DataTemplate>
  114. <TextBlock x:Name="tb" HorizontalAlignment="Left" Foreground="White"
  115. Text="{Binding}" RenderTransformOrigin="0,0" Margin="0,50,0,0">
  116. <TextBlock.RenderTransform>
  117. <RotateTransform Angle="-90"/>
  118. </TextBlock.RenderTransform>
  119. </TextBlock>
  120. </DataTemplate>
  121. </ec:PathListBox.ItemTemplate>
  122. <ec:PathListBox.LayoutPaths>
  123. <ec:LayoutPath Distribution="Even"
  124. Orientation="OrientToPath"
  125. SourceElement="{Binding ElementName=NumberPath}" />
  126. </ec:PathListBox.LayoutPaths>
  127. </ec:PathListBox>
  128. <Path x:Name="LongTickPath"
  129. Data="M0,0 v1"
  130. VerticalAlignment="Top"
  131. HorizontalAlignment="Right"
  132. Stretch="Fill" Fill="Red" Stroke="Red" StrokeThickness="2"
  133. Grid.RowSpan="2"
  134. Margin="0,0"
  135. Focusable="False"
  136. FocusVisualStyle="{x:Null}" />
  137. <Path x:Name="ShortTickPath"
  138. Data="M0,0 V1"
  139. VerticalAlignment="Top"
  140. HorizontalAlignment="Left"
  141. Stretch="Fill"
  142. Grid.RowSpan="2"
  143. Margin="0,0"
  144. Focusable="False"
  145. FocusVisualStyle="{x:Null}" />
  146. <Path x:Name="NumberPath"
  147. Data="M0,0 V1"
  148. Margin="45,0,0,0"
  149. VerticalAlignment="Top"
  150. HorizontalAlignment="Center"
  151. Stretch="Fill"
  152. Grid.RowSpan="2"
  153. Focusable="False"
  154. FocusVisualStyle="{x:Null}" Stroke="Yellow" StrokeThickness="1"/>
  155. </Grid>
  156. </Border>
  157. <StackPanel Grid.Row="3"
  158. Orientation="Horizontal">
  159. <TextBox Width="90"
  160. Height="35"
  161. IsReadOnly="True"
  162. Foreground="{Binding TextboxColor,RelativeSource={RelativeSource AncestorType=UserControl}}"
  163. VerticalAlignment="Center"
  164. Text="{ Binding CurrentValue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Control}}" />
  165. <Label VerticalAlignment="Center"
  166. Content="km"
  167. Foreground="{Binding LabelColor, RelativeSource={RelativeSource AncestorType=UserControl}}"></Label>
  168. </StackPanel>
  169. </Grid>
  170. </UserControl>

  .cs文件:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. namespace INSControls._01Conning.Steer
  15. {
  16. /// <summary>
  17. /// ConningSpeedBar.xaml 的交互逻辑
  18. /// </summary>
  19. public partial class ConningSpeedBar : UserControl
  20. {
  21. public ConningSpeedBar()
  22. {
  23. InitializeComponent();
  24. }
  25. public List<string> TickMarks
  26. {
  27. get { return (List<string>)GetValue(TickMarksProperty); }
  28. set { SetValue(TickMarksProperty, value); }
  29. }
  30. // Using a DependencyProperty as the backing store for TickMarks. This enables animation, styling, binding, etc...
  31. public static readonly DependencyProperty TickMarksProperty =
  32. DependencyProperty.Register("TickMarks", typeof(List<string>), typeof(ConningSpeedBar), new PropertyMetadata(null));
  33. public List<object> LongTicks
  34. {
  35. get { return (List<object>)GetValue(LongTicksProperty); }
  36. set { SetValue(LongTicksProperty, value); }
  37. }
  38. // Using a DependencyProperty as the backing store for LongTicks. This enables animation, styling, binding, etc...
  39. public static readonly DependencyProperty LongTicksProperty =
  40. DependencyProperty.Register("LongTicks", typeof(List<object>), typeof(ConningSpeedBar), new PropertyMetadata(null));
  41. public List<object> ShortTicks
  42. {
  43. get { return (List<object>)GetValue(ShortTicksProperty); }
  44. set { SetValue(ShortTicksProperty, value); }
  45. }
  46. // Using a DependencyProperty as the backing store for ShortTicks. This enables animation, styling, binding, etc...
  47. public static readonly DependencyProperty ShortTicksProperty =
  48. DependencyProperty.Register("ShortTicks", typeof(List<object>), typeof(ConningSpeedBar), new PropertyMetadata(null));
  49. public double CurrentValue
  50. {
  51. get { return (double)GetValue(CurrentValueProperty); }
  52. set { SetValue(CurrentValueProperty, value); }
  53. }
  54. // Using a DependencyProperty as the backing store for CurrentValue. This enables animation, styling, binding, etc...
  55. public static readonly DependencyProperty CurrentValueProperty =
  56. DependencyProperty.Register("CurrentValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(0.0, CurrentValueChangeCallback));
  57. private static void CurrentValueChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  58. {
  59. ConningSpeedBar c = d as ConningSpeedBar;
  60. UpdateUICurrentvalue((double)e.NewValue, c);
  61. }
  62. private static void UpdateUICurrentvalue(double currentValue, ConningSpeedBar c)
  63. {
  64. if (c.mainGrid.ActualHeight==0)
  65. {
  66. return;
  67. }
  68. if (currentValue > 0)
  69. {
  70. c.polygonRotateAngel.Angle = 0;
  71. double totalValue = c.MaxValue - c.MinValue;
  72. //计算显示图形位置
  73. double top = (c.MaxValue - currentValue) * c.mainGrid.ActualHeight / totalValue;
  74. //计算显示图形大小
  75. double height = currentValue * c.mainGrid.ActualHeight / totalValue;
  76. c.graphicGrid.Margin = new Thickness(0, top, 0, 0);
  77. if (height > 40)
  78. {
  79. c.graphicGrid.Height = height;
  80. }
  81. else
  82. {
  83. c.graphicGrid.Height = c.path.Height = height;
  84. }
  85. }
  86. else
  87. {
  88. c.polygonRotateAngel.Angle = 180;
  89. double totalValue = c.MaxValue - c.MinValue;
  90. //计算显示图形位置
  91. double top = (c.MaxValue) * c.mainGrid.ActualHeight / totalValue;
  92. //计算显示图形大小
  93. double height = -currentValue * c.mainGrid.ActualHeight / totalValue;
  94. c.graphicGrid.Margin = new Thickness(0, top, 0, 0);
  95. if (height > 40)
  96. {
  97. c.graphicGrid.Height = height;
  98. }
  99. else
  100. {
  101. c.graphicGrid.Height = c.path.Height = height;
  102. }
  103. }
  104. }
  105. public SolidColorBrush LabelColor
  106. {
  107. get { return (SolidColorBrush)GetValue(LabelColorProperty); }
  108. set { SetValue(LabelColorProperty, value); }
  109. }
  110. // Using a DependencyProperty as the backing store for LabelColor. This enables animation, styling, binding, etc...
  111. public static readonly DependencyProperty LabelColorProperty =
  112. DependencyProperty.Register("LabelColor", typeof(SolidColorBrush), typeof(ConningSpeedBar), new PropertyMetadata(Brushes.Black));
  113. public SolidColorBrush TextboxColor
  114. {
  115. get { return (SolidColorBrush)GetValue(TextboxColorProperty); }
  116. set { SetValue(TextboxColorProperty, value); }
  117. }
  118. // Using a DependencyProperty as the backing store for TextboxColor. This enables animation, styling, binding, etc...
  119. public static readonly DependencyProperty TextboxColorProperty =
  120. DependencyProperty.Register("TextboxColor", typeof(SolidColorBrush), typeof(ConningSpeedBar), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(214, 214, 214))));
  121. public string Title
  122. {
  123. get { return (string)GetValue(TitleProperty); }
  124. set { SetValue(TitleProperty, value); }
  125. }
  126. // Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
  127. public static readonly DependencyProperty TitleProperty =
  128. DependencyProperty.Register("Title", typeof(string), typeof(ConningSpeedBar), new PropertyMetadata(""));
  129. public double MaxValue
  130. {
  131. get { return (double)GetValue(MaxValueProperty); }
  132. set { SetValue(MaxValueProperty, value); }
  133. }
  134. // Using a DependencyProperty as the backing store for MaxValue. This enables animation, styling, binding, etc...
  135. public static readonly DependencyProperty MaxValueProperty =
  136. DependencyProperty.Register("MaxValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(30d));
  137. public double MinValue
  138. {
  139. get { return (double)GetValue(MinValueProperty); }
  140. set { SetValue(MinValueProperty, value); }
  141. }
  142. // Using a DependencyProperty as the backing store for MinValue. This enables animation, styling, binding, etc...
  143. public static readonly DependencyProperty MinValueProperty =
  144. DependencyProperty.Register("MinValue", typeof(double), typeof(ConningSpeedBar), new PropertyMetadata(-10d));
  145. private void UserControl_Loaded(object sender, RoutedEventArgs e)
  146. {
  147. //短刻度
  148. List<object> shortticks = new List<object>();
  149. for (int i = 0; i < 50; i++)
  150. {
  151. shortticks.Add(new object());
  152. }
  153. ShortTicks = shortticks;
  154. //显示刻度文字
  155. List<string> numbers = new List<string>();
  156. //长刻度
  157. List<object> longticks = new List<object>();
  158. for (int i = 0; i < 5; i++)
  159. {
  160. //计算长度信息,等比例地减去间隔值
  161. string tickInfo = (MaxValue - i * (MaxValue - MinValue) / 4).ToString();
  162. numbers.Add(tickInfo+new string('&',i+1));
  163. longticks.Add(new object());
  164. }
  165. LongTicks = longticks;
  166. TickMarks = numbers;
  167. UpdateUICurrentvalue(CurrentValue, this) ;
  168. }
  169. }
  170. }

  源码地址:

https://files.cnblogs.com/files/chlm/%E5%88%BB%E5%BA%A6%E7%BA%BF.rar

 

转载于:https://www.cnblogs.com/chlm/p/9451536.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/270775
推荐阅读
相关标签
  

闽ICP备14008679号