WPF 自定义柱状图 BarChart-程序员宅基地

技术标签: git  ui  

原文: WPF 自定义柱状图 BarChart

WPF 自定义柱状图 

当前的Telerik控件、DevExpress控件在图表控件方面做得不错,但是有时项目中需要特定的样式,不是只通过修改图表的模板和样式就能实现的。

或者说,通过修改当前的第三方控件以达到项目中UI的界面效果,花费的时间远比重新自定义一个控件要长得多!

所以直接自定义柱状图吧~下面是柱状图的效果:

Git代码下载:https://github.com/Kybs0/BarChartControl

1、新建一个UserControl,在界面上添加一些简单的布局

<UserControl x:Class="WpfApplication11.BarChartControl"
            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" 
            mc:Ignorable="d" 
            d:DesignHeight="100" d:DesignWidth="200" Loaded="BarChartControl_OnLoaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid x:Name="HeaderGrid" Grid.Row="0" Grid.Column="1" Height="20">
        </Grid>

        <Grid x:Name="LeftGrid" Grid.Row="1" Grid.Column="0">
        </Grid>
        <Border x:Name="MainBorder" Grid.Row="1" Grid.Column="1" BorderThickness="2,0,2,0" BorderBrush="Black">
        </Border>
        <Grid x:Name="MainGridForRow1" Grid.Row="1" Grid.Column="1">

        </Grid>
        <Grid x:Name="MainGridFrom0To1" Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">

        </Grid>
        <Grid x:Name="RightGrid" Grid.Row="1" Grid.Column="2">
        </Grid>

        <Grid x:Name="BottomGrid" Grid.Row="2" Grid.Column="1">
        </Grid>
    </Grid>
</UserControl>
View Code

2、UserControl的后台界面

通过添加一些依赖属性,然后在后台生成界面。也可以把柱状替换成RadioButton,实现柱状图选择,添加选择事件的委托方法。

 /// <summary>
    /// BarChartControl.xaml 的交互逻辑
    /// </summary>
    public partial class BarChartControl : UserControl
    {
        public BarChartControl()
        {
            InitializeComponent();
        }

        public Brush BorderBrush
        {
            get { return (Brush)GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); }
        }

        public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register("BorderBrush",
        typeof(Brush), typeof(BarChartControl),
        new PropertyMetadata(Brushes.Black));

        public Thickness BorderThickness
        {
            get { return (Thickness)GetValue(BorderThicknessProperty); }
            set { SetValue(BorderThicknessProperty, value); }
        }

        public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register("BorderThickness",
        typeof(Thickness), typeof(BarChartControl),
        new PropertyMetadata(new Thickness(1.0, 0.0, 1.0, 1.0)));

        public AxisYModel AxisY
        {
            get { return (AxisYModel)GetValue(AxisYProperty); }
            set { SetValue(AxisYProperty, value); }
        }

        public static readonly DependencyProperty AxisYProperty = DependencyProperty.Register("AxisY",
        typeof(AxisYModel), typeof(BarChartControl),
        new PropertyMetadata(new AxisYModel()));

        public AxisXModel AxisX
        {
            get { return (AxisXModel)GetValue(AxisXProperty); }
            set { SetValue(AxisXProperty, value); }
        }

        public static readonly DependencyProperty AxisXProperty = DependencyProperty.Register("AxisX",
        typeof(AxisXModel), typeof(BarChartControl),
        new PropertyMetadata(new AxisXModel()));
        public double HeaderHeight
        {
            get { return (double)GetValue(HeaderHeightProperty); }
            set { SetValue(HeaderHeightProperty, value); }
        }
        public static readonly DependencyProperty HeaderHeightProperty = DependencyProperty.Register("HeaderHeight",
        typeof(double), typeof(BarChartControl), new PropertyMetadata(10.0));
        public string Header
        {
            get { return (string)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header",
        typeof(string), typeof(BarChartControl), new PropertyMetadata());

        private void BarChartControl_OnLoaded(object sender, RoutedEventArgs e)
        {
            MainBorder.BorderBrush = BorderBrush;
            MainBorder.BorderThickness = BorderThickness;

            BottomGrid.Height = AxisX.Height;
            LeftGrid.Width = AxisY.Width;

            SetYTitlesContent();

            SetXDatasContent();
        }

        private void SetXDatasContent()
        {
            var axisXModel = AxisX;
            if (axisXModel.Datas.Count > 0)
            {
                int count = axisXModel.Datas.Count;
                for (int i = 0; i < count + 1; i++)
                {
                    BottomGrid.ColumnDefinitions.Add(new ColumnDefinition());
                    MainGridFrom0To1.ColumnDefinitions.Add(new ColumnDefinition());
                }
                int index = 0;
                foreach (var data in axisXModel.Datas)
                {
                    //底部
                    var textblock = new TextBlock();
                    textblock.Text = data.Name;
                    textblock.Foreground = axisXModel.ForeGround;
                    textblock.VerticalAlignment = VerticalAlignment.Top;
                    textblock.TextAlignment = TextAlignment.Center;
                    textblock.HorizontalAlignment = HorizontalAlignment.Right;
                    double textBlockWidth = data.LabelWidth;
                    textblock.Width = data.LabelWidth;
                    textblock.Margin = new Thickness(0, 5, -textBlockWidth / 2, 0);
                    Grid.SetColumn(textblock, index);
                    BottomGrid.Children.Add(textblock);


                    //主内容
                    var stackPanel = new StackPanel();
                    stackPanel.Orientation = Orientation.Vertical;

                    var tbl = new TextBlock();
                    tbl.Height = 15;
                    tbl.Margin = new Thickness(0, 0, 0, 5);
                    tbl.Text = data.Value.ToString();
                    tbl.Foreground = axisXModel.ForeGround;
                    tbl.HorizontalAlignment = HorizontalAlignment.Center;
                    stackPanel.Children.Add(tbl);

                    var rectangle = new Rectangle();
                    rectangle.Width = data.BarWidth;
                    double maxValue = AxisY.Titles.Max(i => i.Value);
                    rectangle.Height = (data.Value / maxValue) * (this.ActualHeight - BottomGrid.Height - HeaderHeight);
                    var linearBrush = new LinearGradientBrush()
                    {
                        StartPoint = new Point(1, 0),
                        EndPoint = new Point(1, 1),
                        GradientStops = new GradientStopCollection() { 
                            new GradientStop()
                            {
                                Color = data.FillBrush, Offset = 0
                            }, new GradientStop()
                            {
                                Color = data.FillEndBrush, Offset = 1
                            }
                        }
                    };
                    rectangle.Fill = linearBrush;
                    rectangle.HorizontalAlignment = HorizontalAlignment.Center;

                    stackPanel.Children.Add(rectangle);
                    stackPanel.Margin = new Thickness(0, 0, -textBlockWidth / 2, 0);
                    stackPanel.VerticalAlignment = VerticalAlignment.Bottom;
                    stackPanel.HorizontalAlignment = HorizontalAlignment.Right;
                    Grid.SetColumn(stackPanel, index);
                    MainGridFrom0To1.Children.Add(stackPanel);
                    index++;
                }
            }
        }

        private void SetYTitlesContent()
        {
            var axisYModel = AxisY;
            if (axisYModel.Titles.Count > 0)
            {
                int gridRows = axisYModel.Titles.Count - 1;
                for (int i = 0; i < gridRows; i++)
                {
                    LeftGrid.RowDefinitions.Add(new RowDefinition());
                    MainGridForRow1.RowDefinitions.Add(new RowDefinition());
                }
                int index = 0;
                foreach (var title in axisYModel.Titles)
                {
                    var textblock = new TextBlock();
                    textblock.Text = title.Name;
                    textblock.Foreground = axisYModel.ForeGround;
                    textblock.HorizontalAlignment = HorizontalAlignment.Right;
                    textblock.Height = title.LabelHeight;
                    if (index < gridRows)
                    {
                        textblock.VerticalAlignment = VerticalAlignment.Bottom;
                        textblock.Margin = new Thickness(0, 0, 5, -title.LabelHeight / 2);//因为设置在行底部还不够,必须往下移
                        Grid.SetRow(textblock, gridRows - index - 1);
                    }
                    else
                    {
                        textblock.VerticalAlignment = VerticalAlignment.Top;
                        textblock.Margin = new Thickness(0, -title.LabelHeight / 2, 5, 0);//最后一个,设置在顶部
                        Grid.SetRow(textblock, 0);
                    }
                    LeftGrid.Children.Add(textblock);

                    var border = new Border();
                    border.Height = title.LineHeight;
                    border.BorderBrush = title.LineBrush;
                    double thickness = Convert.ToDouble(title.LineHeight) / 2;
                    border.BorderThickness = new Thickness(0, thickness, 0, thickness);
                    if (index < gridRows)
                    {
                        border.VerticalAlignment = VerticalAlignment.Bottom;
                        border.Margin = new Thickness(0, 0, 0, -thickness);//因为设置在行底部还不够,必须往下移
                        Grid.SetRow(border, gridRows - index - 1);
                    }
                    else
                    {
                        border.VerticalAlignment = VerticalAlignment.Top;
                        border.Margin = new Thickness(0, -thickness, 0, 0);//最后一个,设置在顶部
                        Grid.SetRow(border, 0);
                    }
                    Grid.SetColumn(border, 0);
                    Grid.SetColumnSpan(border, AxisX.Datas.Count + 1);
                    MainGridForRow1.Children.Add(border);
                    index++;
                }
            }
        }
        /// <summary>
        /// 设置分行
        /// </summary>
        /// <param name="leftGrid"></param>
        /// <param name="count"></param>
        private void SetGridRowDefinitions(Grid leftGrid, int count)
        {
            for (int i = 0; i < count; i++)
            {
                leftGrid.RowDefinitions.Add(new RowDefinition());
            }
        }
    }
    public class AxisXModel
    {
        private double _height = 20;
        /// <summary>
        /// 高度
        /// </summary>
        public double Height
        {
            get
            {
                return _height;
            }
            set { _height = value; }
        }

        private Brush _foreGround = Brushes.Black;
        /// <summary>
        /// 字体颜色
        /// </summary>
        public Brush ForeGround
        {
            get { return _foreGround; }
            set { _foreGround = value; }
        }

        List<AxisXDataModel> _datas = new List<AxisXDataModel>();
        /// <summary>
        /// 数据
        /// </summary>
        public List<AxisXDataModel> Datas
        {
            get { return _datas; }
            set { _datas = value; }
        }
    }
    public class AxisYModel
    {
        private double _width = 20;
        /// <summary>
        /// 宽度
        /// </summary>
        public double Width { get { return _width; } set { _width = value; } }

        private Brush _foreGround = Brushes.Black;
        /// <summary>
        /// 字体颜色
        /// </summary>
        public Brush ForeGround { get { return _foreGround; } set { _foreGround = value; } }

        List<AxisYDataModel> _titles = new List<AxisYDataModel>();
        /// <summary>
        /// 左侧标题列表
        /// </summary>
        public List<AxisYDataModel> Titles
        {
            get { return _titles; }
            set { _titles = value; }
        }
    }
    public class AxisXDataModel : DataModel
    {
        private double _labelWidth = 20;
        /// <summary>
        /// 底部标签-单个宽度
        /// </summary>
        public double LabelWidth
        {
            get { return _labelWidth; }
            set { _labelWidth = value; }
        }
        private double _barWidth = 20;
        /// <summary>
        /// Bar宽度
        /// </summary>
        public double BarWidth
        {
            get { return _barWidth; }
            set { _barWidth = value; }
        }

        private Color _fillBrush = Colors.Blue;
        /// <summary>
        /// Bar填充颜色
        /// </summary>
        public Color FillBrush
        {
            get
            {
                return _fillBrush;
            }
            set { _fillBrush = value; }
        }

        private Color _fillEndBrush = Colors.Blue;

        public Color FillEndBrush
        {
            get
            {
                return _fillEndBrush;
            }
            set { _fillEndBrush = value; }
        }
    }
    public class AxisYDataModel : DataModel
    {
        private double _labelHeight = 15;
        /// <summary>
        /// 左侧标题栏-单个标题高度
        /// </summary>
        public double LabelHeight
        {
            get { return _labelHeight; }
            set { _labelHeight = value; }
        }
        private double _lineHeight = 0.2;
        /// <summary>
        /// GridLine高度
        /// </summary>
        public double LineHeight
        {
            get { return _lineHeight; }
            set { _lineHeight = value; }
        }

        private Brush _lineBrush = Brushes.Blue;
        /// <summary>
        /// Bar填充颜色
        /// </summary>
        public Brush LineBrush
        {
            get { return _lineBrush; }
            set { _lineBrush = value; }
        }
    }
    public class DataModel
    {
        /// <summary>
        /// 显示名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 值
        /// </summary>
        public double Value { get; set; }
    }
View Code

3、主界面引用

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication11="clr-namespace:WpfApplication11"
        x:Class="WpfApplication11.MainWindow"
        Title="MainWindow" Height="350" Width="600" Background="#FF7CADBD">
    <Grid>
        <wpfApplication11:BarChartControl BorderBrush="White" Width="500" Height="250" BorderThickness="2,0,2,0" HeaderHeight="20">
            <wpfApplication11:BarChartControl.AxisY>
                <wpfApplication11:AxisYModel Width="30" ForeGround="White">
                    <wpfApplication11:AxisYModel.Titles>
                        <wpfApplication11:AxisYDataModel Name="0" Value="0"></wpfApplication11:AxisYDataModel>
                        <wpfApplication11:AxisYDataModel Name="20" Value="20"></wpfApplication11:AxisYDataModel>
                        <wpfApplication11:AxisYDataModel Name="40" Value="40"></wpfApplication11:AxisYDataModel>
                        <wpfApplication11:AxisYDataModel Name="60" Value="60"></wpfApplication11:AxisYDataModel>
                        <wpfApplication11:AxisYDataModel Name="80" Value="80"></wpfApplication11:AxisYDataModel>
                        <wpfApplication11:AxisYDataModel Name="100" Value="100"></wpfApplication11:AxisYDataModel>
                    </wpfApplication11:AxisYModel.Titles>
                </wpfApplication11:AxisYModel>
            </wpfApplication11:BarChartControl.AxisY>
            <wpfApplication11:BarChartControl.AxisX>
                <wpfApplication11:AxisXModel Height="30" ForeGround="White">
                    <wpfApplication11:AxisXModel.Datas>
                        <wpfApplication11:AxisXDataModel Name="A" Value="100" FillBrush="DeepSkyBlue" FillEndBrush="#FF6CD7FB"></wpfApplication11:AxisXDataModel>
                        <wpfApplication11:AxisXDataModel Name="B" Value="50"  FillBrush="#FF06F906" FillEndBrush="#FF5CF95C"></wpfApplication11:AxisXDataModel>
                        <wpfApplication11:AxisXDataModel Name="C" Value="70"  FillBrush="Cyan" FillEndBrush="#FF4DFFFF"></wpfApplication11:AxisXDataModel>
                        <wpfApplication11:AxisXDataModel Name="D" Value="30" FillBrush="GreenYellow" FillEndBrush="#FFBFFD60"></wpfApplication11:AxisXDataModel>
                        <wpfApplication11:AxisXDataModel Name="E" Value="86" FillBrush="DarkOrchid" FillEndBrush="#FFCC73F7"></wpfApplication11:AxisXDataModel>
                        <wpfApplication11:AxisXDataModel Name="F" Value="60" FillBrush="Coral" FillEndBrush="#FFF9A181"></wpfApplication11:AxisXDataModel>
                    </wpfApplication11:AxisXModel.Datas>
                </wpfApplication11:AxisXModel>
            </wpfApplication11:BarChartControl.AxisX>
        </wpfApplication11:BarChartControl>
    </Grid>
</Window>
View Code

 以上是通过Grid均分布局来完成的。

之前也尝试过用Canvas来布局,相对来说,在小范围试用还是可以的,定义成控件还是不好,有点局限,比如宽度、高度等,有点死。

GitHub下载地址:https://github.com/Kybs0/WpfApplication9

1、UserControl界面

<UserControl x:Class="WpfApplication9.BarChartControl"
        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" 
        mc:Ignorable="d" Height="200" Width="400"
        d:DesignHeight="200" d:DesignWidth="600" Loaded="BarChartControl_OnLoaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Canvas x:Name="LeftCanvas" Grid.Row="0" Grid.Column="0" Width="30">
        </Canvas>
        <Border x:Name="MainBorder" Grid.Row="0" Grid.Column="1" BorderThickness="2,0,2,2" BorderBrush="Black" Padding="2,0,1,0">
            <Canvas x:Name="MainCanvas">

            </Canvas>
        </Border>
        <Canvas x:Name="RightCanvas" Grid.Row="0" Grid.Column="2">
        </Canvas>

        <Canvas x:Name="BottomCanvas" Grid.Row="1" Grid.Column="1" Height="30">
        </Canvas>
    </Grid>
</UserControl>
View Code

2、UserControl后台

 public partial class BarChartControl : UserControl
    {
        public BarChartControl()
        {
            InitializeComponent();
        }

        public Brush BorderBrush
        {
            get { return (Brush) GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); }
        }

        public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register("BorderBrush",
            typeof (Brush), typeof (BarChartControl),
            new PropertyMetadata(Brushes.Black));

        public Thickness BorderThickness
        {
            get { return (Thickness) GetValue(BorderThicknessProperty); }
            set { SetValue(BorderThicknessProperty, value); }
        }

        public static readonly DependencyProperty BorderThicknessProperty =
            DependencyProperty.Register("BorderThickness",
                typeof (Thickness), typeof (BarChartControl),
                new PropertyMetadata(new Thickness(1.0, 0.0, 1.0, 1.0)));

        public AxisYModel AxisY
        {
            get { return (AxisYModel) GetValue(AxisYProperty); }
            set { SetValue(AxisYProperty, value); }
        }

        public static readonly DependencyProperty AxisYProperty = DependencyProperty.Register("AxisY",
            typeof (AxisYModel), typeof (BarChartControl),
            new PropertyMetadata(new AxisYModel()));

        public AxisXModel AxisX
        {
            get { return (AxisXModel) GetValue(AxisXProperty); }
            set { SetValue(AxisXProperty, value); }
        }

        public static readonly DependencyProperty AxisXProperty = DependencyProperty.Register("AxisX",
            typeof (AxisXModel), typeof (BarChartControl),
            new PropertyMetadata(new AxisXModel()));

        private void BarChartControl_OnLoaded(object sender, RoutedEventArgs e)
        {
            MainBorder.BorderBrush = BorderBrush;
            MainBorder.BorderThickness = BorderThickness;

            SetYTitlesContent();

            SetXDatasContent();
        }

        private void SetXDatasContent()
        {
            var axisXModel = AxisX;
            if (axisXModel.Datas.Count > 0)
            {
                BottomCanvas.Height = axisXModel.Height;
                double width = MainBorder.ActualWidth;


                int count = axisXModel.Datas.Count;
                int index = 1;
                foreach (var data in axisXModel.Datas)
                {
                    var textblock = new TextBlock();
                    textblock.Text = data.Name;
                    textblock.Foreground = axisXModel.ForeGround;
                    textblock.TextAlignment = TextAlignment.Center;
                    //textblock.VerticalAlignment = VerticalAlignment.Top;
                    //textblock.Height = axisXModel.Height;
                    double textBlockWidth = axisXModel.LabelWidth;
                    textblock.Width = textBlockWidth;
                    //textblock.Padding = new Thickness(0, 0, 5, 0);
                    double leftLength = width*Convert.ToDouble(index)/(count + 1) - textBlockWidth/2;
                    Canvas.SetLeft(textblock, leftLength);
                    BottomCanvas.Children.Add(textblock);

                    var stackPanel = new StackPanel();
                    stackPanel.Orientation = Orientation.Vertical;

                    var tbl = new TextBlock();
                    tbl.Height = 15;
                    tbl.Margin = new Thickness(0, 0, 0, 5);
                    tbl.Text = data.Value.ToString();
                    stackPanel.Children.Add(tbl);

                    var rectangle = new Rectangle();
                    rectangle.Width = data.BarWidth;
                    double maxValue = AxisY.Titles.Max(i => i.Value);
                    rectangle.Height = (data.Value/maxValue)*MainCanvas.ActualHeight;
                    var linearBrush = new LinearGradientBrush()
                    {
                        StartPoint = new Point(1, 0),
                        EndPoint = new Point(1, 1),
                        GradientStops = new GradientStopCollection()
                        {
                            new GradientStop()
                            {
                                Color = data.FillBrush,
                                Offset = 0
                            },
                            new GradientStop()
                            {
                                Color = data.FillEndBrush,
                                Offset = 1
                            }
                        }
                    };
                    rectangle.Fill = linearBrush;
                    stackPanel.Children.Add(rectangle);

                    double leftBarLength = width*Convert.ToDouble(index)/(count + 1) - data.BarWidth/2;
                    Canvas.SetLeft(stackPanel, leftBarLength);

                    Canvas.SetTop(stackPanel, MainCanvas.ActualHeight - (rectangle.Height + 20));

                    MainCanvas.Children.Add(stackPanel);
                    index++;
                }
            }
        }

        private void SetYTitlesContent()
        {
            var axisYModel = AxisY;
            if (axisYModel.Titles.Count > 0)
            {
                LeftCanvas.Width = axisYModel.Width;
                double height = MainBorder.ActualHeight;

                int index = 0;
                int count = axisYModel.Titles.Count;
                foreach (var title in axisYModel.Titles)
                {
                    var textblock = new TextBlock();
                    textblock.Text = title.Name;
                    textblock.Foreground = axisYModel.ForeGround;
                    textblock.TextAlignment = TextAlignment.Right;
                    textblock.Width = axisYModel.Width;
                    double textBlockHeight = 18;
                    textblock.Height = textBlockHeight;
                    textblock.Padding = new Thickness(0, 0, 5, 0);
                    double topLength = height - height*Convert.ToDouble(index)/(count - 1) - textBlockHeight/2;
                    Canvas.SetTop(textblock, topLength);
                    LeftCanvas.Children.Add(textblock);

                    var path = new Path();
                    path.Stroke = Brushes.DodgerBlue;
                    path.StrokeThickness = 0.5;

                    var startPoint = new Point(0, height - height*Convert.ToDouble(index)/(count - 1));
                    var endPoint = new Point(MainCanvas.ActualWidth, height - height*Convert.ToDouble(index)/(count - 1));
                    path.Data = new PathGeometry()
                    {
                        Figures = new PathFigureCollection()
                        {
                            new PathFigure()
                            {
                                IsClosed = true,
                                StartPoint = startPoint,
                                Segments = new PathSegmentCollection()
                                {
                                    new LineSegment() {Point = endPoint}
                                }
                            }
                        }
                    };
                    MainCanvas.Children.Add(path);
                    index++;
                }
            }
        }
    }

    public class AxisXModel
    {
        public double Height { get; set; }

        private double _lableWidth = 50;

        public double LabelWidth
        {
            get { return _lableWidth; }
            set { _lableWidth = value; }
        }

        public Brush ForeGround { get; set; }
        private List<DataModel> _titles = new List<DataModel>();

        public List<DataModel> Datas
        {
            get { return _titles; }
            set { _titles = value; }
        }
    }

    public class AxisYModel
    {
        public double Width { get; set; }

        public Brush ForeGround { get; set; }

        private List<DataModel> _titles = new List<DataModel>();

        public List<DataModel> Titles
        {
            get { return _titles; }
            set { _titles = value; }
        }
    }

    public class DataModel
    {
        public string Name { get; set; }
        public double Value { get; set; }

        private double _barWidth = 20;

        public double BarWidth
        {
            get { return _barWidth; }
            set { _barWidth = value; }
        }

        public Color FillBrush { get; set; }
        public Color FillEndBrush { get; set; } 
    }
View Code

3、引用

<Window x:Class="WpfApplication9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication9="clr-namespace:WpfApplication9"
        Title="MainWindow" Height="350" Width="600" Background="LightGray">
    <Grid>
        <wpfApplication9:BarChartControl BorderBrush="White" Width="500" BorderThickness="2,0,2,0">
            <wpfApplication9:BarChartControl.AxisY>
                <wpfApplication9:AxisYModel Width="30" ForeGround="White">
                    <wpfApplication9:AxisYModel.Titles>
                        <wpfApplication9:DataModel Name="0" Value="0"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="20" Value="20"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="40" Value="40"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="60" Value="60"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="80" Value="80"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="100" Value="100"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="120" Value="120">
                        </wpfApplication9:DataModel>
                    </wpfApplication9:AxisYModel.Titles>
                </wpfApplication9:AxisYModel>
            </wpfApplication9:BarChartControl.AxisY>
            <wpfApplication9:BarChartControl.AxisX>
                <wpfApplication9:AxisXModel Height="30" ForeGround="White">
                    <wpfApplication9:AxisXModel.Datas>
                        <wpfApplication9:DataModel Name="A" Value="99" FillBrush="Red" FillEndBrush="#FFFD8585"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="B" Value="20" FillBrush="Yellow" FillEndBrush="Yellow"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="C" Value="40" FillBrush="Blue" FillEndBrush="Blue"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="D" Value="60" FillBrush="Green" FillEndBrush="CornflowerBlue"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="E" Value="80" FillBrush="DeepSkyBlue" FillEndBrush="CornflowerBlue"></wpfApplication9:DataModel>
                        <wpfApplication9:DataModel Name="F" Value="100" FillBrush="CornflowerBlue" FillEndBrush="CornflowerBlue"></wpfApplication9:DataModel>
                    </wpfApplication9:AxisXModel.Datas>
                </wpfApplication9:AxisXModel>
            </wpfApplication9:BarChartControl.AxisX>
        </wpfApplication9:BarChartControl>
    </Grid>
</Window>
View Code

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34168700/article/details/89595054

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签