一、先看效果

从头实现一个WPF条形图

二、本文背景

有没有这种场景:开源控件库或者收费的控件库,条形图或者柱状图都非常强大,但我的业务就是不符合,就是要自己设计呢?本文通过简单的实现一个条形图功能,以后类似的统计图可以在这上面进行修改,原理是类似的。

三、代码实现

小编使用.Net Core 3.1创建的WPF工程,创建名称为“BarChart”的解决方案后,添加名称为”Bar“的WPF用户控件,这个控件就是上图中的单个柱子,下面是Bar.xaml代码

 1 <UserControl x:Class="BarChart.Bar" 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              mc:Ignorable="d"  7              MinHeight="20" Width="Auto" Loaded="UserControl_Loaded"> 8     <Grid SizeChanged="Grid_SizeChanged"> 9         <Grid Background="{Binding Background,ElementName=border}" Opacity="0.3"/>10         <Border x:Name="border" Background="{Binding Color}" VerticalAlignment="Bottom" Height="{Binding BarHeight}"/>11         <TextBlock VerticalAlignment="Center" Margin="3" HorizontalAlignment="Center" Text="{Binding Value}" FontSize="20">12             <TextBlock.Effect>13                 <DropShadowEffect BlurRadius="1" ShadowDepth="0" Color="White"/>14             TextBlock.Effect>15         TextBlock>16     Grid>17 UserControl>

 

Bar.xaml.cs代码,主要是绑定前景色及背景色,及柱子百分比值。

 1 using System.ComponentModel; 2 using System.Windows; 3 using System.Windows.Controls; 4 using System.Windows.Media; 5  6 namespace BarChart 7 { 8     ///  9     /// BarChart.xaml 的交互逻辑10     /// 11     public partial class Bar  : UserControl, INotifyPropertyChanged12     {13         public event PropertyChangedEventHandler PropertyChanged;14         private void NotifyPropertyChanged(string info)15         {16             if (PropertyChanged != null)17             {18                 PropertyChanged(this, new PropertyChangedEventArgs(info));19             }20         }21 22         private double _value;23         public double Value24         {25             get { return _value; }26             set27             {28                 _value = value;29                 UpdateBarHeight();30                 NotifyPropertyChanged("Value");31             }32         }33 34         private double maxValue;35         public double MaxValue36         {37             get { return maxValue; }38             set39             {40                 maxValue = value;41                 UpdateBarHeight();42                 NotifyPropertyChanged("MaxValue");43             }44         }45 46         private double barHeight;47         public double BarHeight48         {49             get { return barHeight; }50             set51             {52                 barHeight = value;53                 NotifyPropertyChanged("BarHeight");54             }55         }56 57         private Brush color;58         public Brush Color59         {60             get { return color; }61             set62             {63                 color = value;64                 NotifyPropertyChanged("Color");65             }66         }67 68         private void UpdateBarHeight()69         {70             if (maxValue > 0)71             {72                 var percent = (_value * 100) / maxValue;73                 BarHeight = (percent * this.ActualHeight) / 100;74             }75         }76 77         public Bar()78         {79             InitializeComponent();80 81             this.DataContext = this;82             color = Brushes.Black;83         }84 85 86         private void UserControl_Loaded(object sender, RoutedEventArgs e)87         {88             UpdateBarHeight();89         }90 91         private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)92         {93             UpdateBarHeight();94         }95     }96 }

 

主窗体MainWindow.xaml,添加显示的业务数据,目前只是展示了进度值,其他标签只要你看懂了代码,很好加的,比如每根柱子,上面颜色显示一种意义名称、下面显示另一种意义名称。

 1 <Window x:Class="BarChart.MainWindow" 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6         xmlns:local="clr-namespace:BarChart" 7         mc:Ignorable="d" 8         Background="#FF252525" FontFamily="Nontserrrat" 9         Title="MainWindow" Height="600" Width="1080" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">10     <Grid>11         <Grid.RowDefinitions>12             <RowDefinition Height="70"/>13             <RowDefinition Height="*"/>14         Grid.RowDefinitions>15 16         <Border BorderBrush="Gray" BorderThickness="0 0 0 1">17             <TextBlock Text="Dotnet9.com" VerticalAlignment="Center" Margin="15"18                        Foreground="White" FontSize="24"/>19         Border>20 21         <Border Grid.Row="1" Width="500" Height="300" VerticalAlignment="Top"22                 HorizontalAlignment="Left" Margin="20" Background="White"23                 BorderBrush="Gray" CornerRadius="12">24             <Grid>25                 <TextBlock Text="自定义条形图" Margin="10" FontSize="15"/>26                 <StackPanel Orientation="Horizontal" Height="200" VerticalAlignment="Bottom">27                     <local:Bar Background="#FF4455AA" Color="#FF88AA55" MaxValue="100" Value="80" Margin="5"/>28                     <local:Bar Background="#FF4335AA" Color="#FF883355" MaxValue="100" Value="26" Margin="5"/>29                     <local:Bar Background="#F26455AA" Color="#FF88A355" MaxValue="100" Value="49" Margin="5"/>30                     <local:Bar Background="#FF4423AA" Color="#FF88A115" MaxValue="100" Value="23" Margin="5"/>31                     <local:Bar Background="#FF4415AA" Color="#FF887955" MaxValue="100" Value="97" Margin="5"/>32                     <local:Bar Background="#FF44513A" Color="#FF896A55" MaxValue="100" Value="68" Margin="5"/>33                 StackPanel>34             Grid>35         Border>36     Grid>37 Window>