在这片文章中我们介绍了如何将柱状图包装成一个组件,将这个组件的属性对外开放和组件的外部属性根内部属性绑定以及非轮询动态更新数据的方式。
非轮询更新数据感觉介绍的不够详细的请看这篇文章
WPF非轮询方式更新数据库变化SqlDependency(数据库修改前台自动更新)
然而柱状图组件讲了这么多 组件是有了 但是没有柱状图。今天去讲一下柱状图。
关于柱状图呢
我这里用的也是网上下载下来的,我们今天讲组件的数据动态化,不关注具体的柱状图怎么画,而是让当组件的属性发生更改的时候,柱状图也会变化。
网上一般很少有这种资料,今天我们自己去改。
首先我们怎样将组件的属性和柱状图的属性去绑定呢?
在之前的文章中我们知道柱状图是一个用户控件,我们去为这个用户控件注册依赖属性。
public static DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(BarChart));public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
在这段代码中,注册了一个属性和依赖属性,title为柱状图的一个标题。
接下来将这个Title绑定到柱状图的Title上。
Binding titleBind = new Binding { Source = this, Path = new PropertyPath("Title") };
BindingOperations.SetBinding(this.txtTopTitle, TextBlock.TextProperty, titleBind);
this.txtTopTitle是用户控件上的一个textblock控件,用这种方式绑定即可。
现在只是将属性和用户控件绑定了 那么数据怎么来的呢?
在组件获取数据的地方 加上
Binding titleBind = new Binding { Source = this, Path = new PropertyPath("Title") };
BindingOperations.SetBinding(this.chart2, BarChart.TitleProperty, titleBind);
this.chart2是柱状图用户控件,BarChart.TitleProperty是我们注册的依赖属性
这样一来只要外部的组件属性发生改变 内部的柱状图也会发生改变
柱状图的数据变得动也是同理
/// <summary>
/// Creates the chart based on the datasource.
/// </summary>
public void Generate()
{
try
{
left = 0;
legends.Clear();
chartArea.Children.Clear();// Setup chart elements.
AddChartControlsToChart();// Setup chart area.
SetUpChartArea();// Will be made more generic in the next versions.
DataTable dt = (DataSource as DataSet).Tables[0];if (null != dt)
{
// if no data found draw empty chart.
if (dt.Rows.Count == 0)
{
DrawEmptyChart();
return;
}// Hide the nodata found text.
txtNoData.Visibility = Visibility.Hidden;// Get the max y-value. This is used to calculate the scale and y-axis.
maxData = GetMax(dt);// Prepare the chart for rendering. Does some basic setup.
PrepareChartForRendering();// Get the total bar count.
int barCount = dt.Rows.Count;
// If more than 1 value field, then this is a group chart.
bool isSeries = ValueField.Count > 1;// no legends added yet.
bool legendAdded = false; // no legends yet added.// For each row in the datasource
foreach (DataRow row in dt.Rows)
{
// Draw x-axis label based on datarow.
DrawXAxisLabel(row);// Set the barwidth. This is required to adjust the size based on available no. of
// bars.
SetBarWidth(barCount);// For each row the current series is initialized to 0 to indicate start of series.
int currentSeries = 0;// For each value in the datarow, draw the bar.
foreach (string valField in ValueField)
{
if (null == valField)
continue;if (!row.Table.Columns.Contains(valField))
continue;// Draw bar for each value.
DrawBar(isSeries, legendAdded, row, ref currentSeries, valField);}
legendAdded = true;// Set up location for next bar in series.
if (isSeries)
left = left + spaceBetweenBars;
}// Reset the chartarea to accomdodate all the chart elements.
if ((left + BarWidth) > chartArea.Width)
chartArea.Width = left + BarWidth;// Draw the x-axis.
DrawXAxis();// Draw the y-axis.
DrawYAxis();// Draw the legend.
DrawLegend();
}
}
catch (Exception ex)
{
// TODO: Finalize exception handling strategy.
MessageBox.Show(ex.Message);
}
}
这是画柱状图的代码,要达到动态变动的效果,还需要加入如下代码:
private DataSet data;
private bool showBar;
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
//DataTable dt = data.Tables[0];if (data != DataSource || showBar != ShowValueOnBar)
Generate();
data = DataSource;
showBar = ShowValueOnBar;
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
if (data != DataSource || showBar != ShowValueOnBar)
Generate();
data = DataSource;
showBar = ShowValueOnBar;
}
在属性和内容发生变动的时候重新绘图,达到数据变动的效果。
需要全部源码的请加群。
WPF、AE技术交流群:94234450
我们不能保证解决任何问题,但绝不会让你独自去面对!
WPF柱状图(支持数据库动态更新)之组件的数据动态化