1127 lines
32 KiB
C#

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Charts
{
///<summary>
/// DataBinding helper class
///</summary>
public class DataBinder : IDisposable
{
#region Private variables
private readonly ChartControl _ChartControl;
private readonly BaseChart _Chart;
private readonly BaseSeries _Series;
private CurrencyManager _CurrencyManager;
private PropertyDescriptorCollection _Pdc;
private DataView _DataView;
private BindingSource _BindingSource;
private BindingSource _BaseBindingSource;
private object _BaseDataSource;
private string _BaseDataMember;
private bool _NotificationAutogen;
private bool _NotificationInProgress;
private int _SeriesCount;
#endregion
///<summary>
/// DataBinding
///</summary>
///<param name="panel"></param>
internal DataBinder(BaseChart chart)
{
_Chart = chart;
_ChartControl = chart.ChartControl;
}
internal DataBinder(BaseSeries series)
{
_Series = series;
_Chart = series.Parent as BaseChart;
_ChartControl = _Chart.ChartControl;
}
#region Internal properties
#region BaseDataMember
internal string BaseDataMember
{
get { return (_BaseDataMember); }
set { _BaseDataMember = value; }
}
#endregion
#region BaseDataSource
internal object BaseDataSource
{
get { return (_BaseDataSource); }
set { _BaseDataSource = value; }
}
#endregion
#region CurrencyManager
internal CurrencyManager CurrencyManager
{
get { return (_CurrencyManager); }
set
{
if (_CurrencyManager != value)
{
if (_CurrencyManager != null)
_CurrencyManager.ListChanged -= CurrencyManagerListChanged;
_CurrencyManager = value;
_BaseBindingSource = null;
if (_CurrencyManager != null)
{
_Pdc = CurrencyManager.GetItemProperties();
_BaseBindingSource = _BaseDataSource as BindingSource;
_CurrencyManager.ListChanged += CurrencyManagerListChanged;
}
else
{
_Pdc = null;
}
}
}
}
#endregion
#region DataView
internal DataView DataView
{
get { return (_DataView); }
set { _DataView = value; }
}
#endregion
#region GetValue
internal object GetValue(int index, string name)
{
if (CurrencyManager != null && _Pdc != null)
{
if ((uint)index < CurrencyManager.List.Count)
{
object dataItem = CurrencyManager.List[index];
PropertyDescriptorCollection pdc = GetPdc(dataItem);
PropertyDescriptor pd = FindPropertyDescriptor(pdc, name);
if (pd != null)
return (pd.GetValue(dataItem));
}
}
return (null);
}
#endregion
#region Pdc
internal PropertyDescriptorCollection Pdc
{
get { return (_Pdc); }
set { _Pdc = value; }
}
#endregion
#region RowCount
internal int RowCount
{
get
{
if (CurrencyManager != null)
return (CurrencyManager.Count);
return (0);
}
}
#endregion
#endregion
#region Clear
internal void Clear()
{
CurrencyManager = null;
}
#endregion
#region DataConnect
internal object DataConnect(object dataSource, string dataMember)
{
_BaseDataSource = dataSource;
_BaseDataMember = dataMember;
if (_BaseDataSource != null)
{
_BindingSource = _BaseDataSource as BindingSource;
if (_BindingSource != null)
{
BindingSource bs = _BindingSource.DataSource as BindingSource;
if (bs != null)
{
if (string.IsNullOrEmpty(_BindingSource.DataMember) == false)
_BaseDataMember = _BindingSource.DataMember;
else
_BindingSource = null;
while (bs.DataSource is BindingSource)
bs = (BindingSource)bs.DataSource;
DataSet dss = bs.DataSource as DataSet;
if (dss != null)
{
DataRelation dsr = dss.Relations[_BaseDataMember];
if (dsr != null)
{
_BaseDataSource = dss;
_BaseDataMember = dsr.ChildTable.TableName;
}
}
}
else
{
_BaseDataSource = _BindingSource.DataSource;
_BaseDataMember = _BindingSource.DataMember;
}
}
DataView = null;
if (_BaseDataSource is DataSet)
return (AddDataSetTable((DataSet)_BaseDataSource, _BaseDataMember));
if (_BaseDataSource is DataTable)
return (AddDataTable((DataTable)_BaseDataSource));
if (_BaseDataSource is IListSource)
return (AddList(((IListSource)_BaseDataSource).GetList()));
return (AddList(_BaseDataSource));
}
return (null);
}
#endregion
#region AddList
internal object AddList(object source)
{
bool autogen = _Chart.AutoGenSeriesCollection;
if (_ChartControl.DoDataBindingStartEvent(_Chart, source, ref autogen) == false)
return (AddList(source, autogen));
return (null);
}
internal object AddList(object source, bool autogen)
{
if (_Series == null)
{
if (SetDataConnection(source, autogen) == true)
ProcessAddList(source, autogen);
}
else
{
SetDataConnection(source, false);
}
return (source);
}
#region ProcessAddList
private void ProcessAddList(object source, bool autogen)
{
if (_Pdc != null)
{
if (autogen == true && _ChartControl.DesignerHosted == false)
AutoGenerateListSeries(source);
foreach (ChartSeries series in _Chart.BaseSeries)
series.NeedToUpdateBindings = true;
}
}
#region AutoGenerateListSeries
private void AutoGenerateListSeries(object source)
{
string nameSeries = _Chart.DataPropertyNameSeries;
string nameX = GetListNameX(nameSeries);
CustomCollection<string> namesY = GetListNamesY(nameSeries, nameX);
if (string.IsNullOrEmpty(nameSeries) == true)
AutoGenListSeriesSingle(nameX, namesY);
else
AutoGenListSeriesMultiple(source, nameSeries, nameX, namesY);
}
#region AutoGenListSeriesSingle
private void AutoGenListSeriesSingle(
string nameX, CustomCollection<string> namesY)
{
BaseSeries series = _Chart.GetNewSeries();
series.DataPropertyNameX = nameX;
series.DataPropertyNamesY = namesY;
SetAutoSeriesId(series);
_Chart.AddChartSeries(series);
}
#endregion
#region AutoGenListSeriesMultiple
private void AutoGenListSeriesMultiple(object source,
string nameSeries, string nameX, CustomCollection<string> namesY)
{
PropertyDescriptor pdSeries = FindListPd(nameSeries);
if (pdSeries == null)
throw new Exception("List series name not found (" + nameSeries + ")");
object lastSeriesKey = null;
IList list = source as IList;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
object o = list[i];
if (o != null)
{
object seriesKey = pdSeries.GetValue(o);
if ((lastSeriesKey != null) && (seriesKey != lastSeriesKey))
AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY);
lastSeriesKey = seriesKey;
}
}
if (lastSeriesKey != null)
AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY);
}
}
#endregion
#region GetListNameX
private string GetListNameX(string nameSeries)
{
string nameX = _Chart.DataPropertyNameX;
if (string.IsNullOrEmpty(nameX) == false)
{
if (FindListPd(nameX) == null)
throw new Exception("Cannot find List Property (" + nameX + ")");
return (nameX);
}
bool emptyNameSeries = string.IsNullOrEmpty(nameSeries);
foreach (PropertyDescriptor pd in _Pdc)
{
if (IsAccessibleItem(pd) == true)
{
if (emptyNameSeries == true || emptyNameSeries.Equals(pd.Name) == false)
return (pd.Name);
}
}
throw new Exception("Cannot determine auto-assigned DataPropertyNameX.");
}
#endregion
#region GetListNamesY
private CustomCollection<string>
GetListNamesY(string nameSeries, string nameX)
{
CustomCollection<string> namesY = _Chart.DataPropertyNamesY;
if (namesY == null)
namesY = new CustomCollection<string>();
if (namesY.Count == 0)
{
int countY = _Chart.GetAutoGenSeriesNameCount();
foreach (PropertyDescriptor pd in _Pdc)
{
if (IsAccessibleItem(pd) == true)
{
if ((nameSeries == null || nameSeries.Equals(pd.Name) == false)
&& nameX.Equals(pd.Name) == false)
{
namesY.Add(pd.Name);
if (--countY == 0)
return (namesY);
}
}
}
throw new Exception("Cannot determine auto-assigned DataPropertyNamesY.");
}
return (namesY);
}
#endregion
#region FindListPd
private PropertyDescriptor FindListPd(string nameX)
{
foreach (PropertyDescriptor pd in _Pdc)
{
if (IsAccessibleItem(pd) == true)
{
if (pd.Name.Equals(nameX) == true)
return (pd);
}
}
return (null);
}
#endregion
#region IsAccessibleItem
private bool IsAccessibleItem(PropertyDescriptor pd)
{
if (pd.PropertyType.IsInterface == false)
{
if (IsNestedList(pd.PropertyType.Name) == false && IsVisibleItem(pd) == true)
return (true);
}
return (false);
}
#region IsNestedList
private bool IsNestedList(string name)
{
return (name.Equals("List`1") || name.Equals("BindingList`1"));
}
#endregion
#region IsVisibleItem
private bool IsVisibleItem(PropertyDescriptor pd)
{
foreach (Attribute attr in pd.Attributes)
{
IsVisibleToChartControl dattr = attr as IsVisibleToChartControl;
if (dattr != null)
return (dattr.Visible);
}
return (true);
}
#endregion
#endregion
#endregion
#endregion
#endregion
#region AddDataSetTable
internal object AddDataSetTable(DataSet dataSet, string dataMember)
{
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (string.IsNullOrEmpty(dataMember) == false)
return (AddDataTable(dataSet.Tables[dataMember]));
return (null);
}
#endregion
#region AddDataTable
internal object AddDataTable(DataTable dt)
{
if (_Series == null)
{
bool autogen = _Chart.AutoGenSeriesCollection;
if (_ChartControl.DoDataBindingStartEvent(_Chart, dt, ref autogen) == false)
{
if (SetDataConnection(dt, autogen) == true)
{
if (CurrencyManager != null)
ProcessAddDataTable(dt, autogen);
}
}
}
else
{
SetDataConnection(dt, false);
}
return (dt);
}
#region ProcessAddDataTable
private void ProcessAddDataTable(DataTable dt, bool autogen)
{
if (autogen == true && _ChartControl.DesignerHosted == false)
AutoGenerateDataTableSeries(dt);
dt.DefaultView.RowFilter = "";
DataView = dt.DefaultView;
ChartBaseSeriesCollection baseSeries = _Chart.BaseSeries;
foreach (BaseSeries series in baseSeries)
series.NeedToUpdateBindings = true;
}
#region AutoGenerateDataTableSeries
private void AutoGenerateDataTableSeries(DataTable dt)
{
string nameSeries = _Chart.DataPropertyNameSeries;
string nameX = GetDataTableNameX(dt, nameSeries);
CustomCollection<string> namesY = GetDataTableNamesY(dt, nameSeries, nameX);
if (string.IsNullOrEmpty(nameSeries) == true)
AutoGenDataTableSeriesSingle(dt, nameX, namesY);
else
AutoGenDataTableSeriesMultiple(dt, nameSeries, nameX, namesY);
}
#region AutoGenDataTableSeriesSingle
private void AutoGenDataTableSeriesSingle(
DataTable dt, string nameX, CustomCollection<string> namesY)
{
BaseSeries series = _Chart.GetNewSeries();
series.DataPropertyNameX = nameX;
series.DataPropertyNamesY = namesY;
SetAutoSeriesId(series);
_Chart.AddChartSeries(series);
}
#endregion
#region AutoGenDataTableSeriesMultiple
private void AutoGenDataTableSeriesMultiple(DataTable dt,
string nameSeries, string nameX, CustomCollection<string> namesY)
{
DataColumn dtSeries = FindDataColumn(dt, nameSeries);
if (dtSeries == null)
throw new Exception("DataTable series name not found (" + nameSeries + ")");
object lastSeriesKey = null;
for (int i = 0; i < CurrencyManager.Count; i++)
{
DataRowView view = CurrencyManager.List[i] as DataRowView;
if (view != null)
{
object seriesKey = view.Row.ItemArray[dtSeries.Ordinal];
if ((lastSeriesKey != null) && (seriesKey != lastSeriesKey))
AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY);
lastSeriesKey = seriesKey;
}
}
if (lastSeriesKey != null)
AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY);
}
#region AddAutoGenSeries
private void AddAutoGenSeries(object seriesKey,
string nameSeries, string nameX, CustomCollection<string> namesY)
{
string name = seriesKey.ToString();
if (FindChartSeries(name) == null)
{
BaseSeries series = _Chart.GetNewSeries();
series.SeriesId = ++_SeriesCount;
series.Name = name;
series.SeriesKey = seriesKey;
series.DataPropertyNameSeries = nameSeries;
series.DataPropertyNameX = nameX;
series.DataPropertyNamesY = namesY;
_Chart.AddChartSeries(series);
}
}
#endregion
#endregion
#region GetDataTableNameX
private string GetDataTableNameX(DataTable dt, string nameSeries)
{
string nameX = _Chart.DataPropertyNameX;
if (string.IsNullOrEmpty(nameX) == false)
{
if (FindDataColumn(dt, nameX) == null)
throw new Exception("Cannot find DataColumn (" + nameX + ")");
return (nameX);
}
bool emptyNameSeries = string.IsNullOrEmpty(nameSeries);
foreach (DataColumn dtColumn in dt.Columns)
{
if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden)
{
if (emptyNameSeries == true || emptyNameSeries.Equals(dtColumn.ColumnName) == false)
return (dtColumn.ColumnName);
}
}
throw new Exception("Cannot determine auto-assigned DataPropertyNameX.");
}
#endregion
#region GetDataTableNamesY
private CustomCollection<string>
GetDataTableNamesY(DataTable dt, string nameSeries, string nameX)
{
CustomCollection<string> namesY = _Chart.DataPropertyNamesY;
if (namesY == null)
namesY = new CustomCollection<string>();
if (namesY.Count == 0)
{
int countY = _Chart.GetAutoGenSeriesNameCount();
foreach (DataColumn dtColumn in dt.Columns)
{
if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden)
{
if ((nameSeries == null || nameSeries.Equals(dtColumn.ColumnName) == false)
&& nameX.Equals(dtColumn.ColumnName) == false)
{
namesY.Add(dtColumn.ColumnName);
if (--countY == 0)
return (namesY);
}
}
}
throw new Exception("Cannot determine auto-assigned DataPropertyNamesY.");
}
return (namesY);
}
#endregion
#endregion
#region FindDataColumn
private DataColumn FindDataColumn(DataTable dt, string name)
{
if (string.IsNullOrEmpty(name) == false)
{
foreach (DataColumn dtColumn in dt.Columns)
{
if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden)
{
if (dtColumn.ColumnName.Equals(name) == true)
return (dtColumn);
}
}
}
return (null);
}
#endregion
#endregion
#endregion
#region SetAutoSeriesId
private void SetAutoSeriesId(BaseSeries series)
{
series.SeriesId = ++_SeriesCount;
series.Name = GetUniqueSeriesName(series);
}
#region GetUniqueSeriesName
private string GetUniqueSeriesName(BaseSeries series)
{
string name = "Series" + series.SeriesId;
while (FindChartSeries(name) != null)
name += "*";
return (name);
}
#endregion
#endregion
#region SetDataConnection
private bool SetDataConnection(object dataSource, bool autogen)
{
ClearDataNotification(dataSource);
if (_BindingSource != null || _ChartControl.BindingContext != null)
SetDataNotification(dataSource, autogen);
return (_NotificationInProgress == false);
}
#endregion
#region SetDataNotification
private void SetDataNotification(object dataSource, bool autogen)
{
ISupportInitializeNotification notification =
dataSource as ISupportInitializeNotification;
if (notification == null || notification.IsInitialized == true)
{
CurrencyManager = (_BindingSource != null)
? _BindingSource.CurrencyManager
: _ChartControl.BindingContext[DataView ?? dataSource] as CurrencyManager;
}
else
{
CurrencyManager = null;
if (_NotificationInProgress == false)
{
_NotificationInProgress = true;
_NotificationAutogen = autogen;
notification.Initialized += DataSourceInitialized;
}
}
}
#endregion
#region ClearDataNotification
private void ClearDataNotification(object dataSource)
{
ISupportInitializeNotification notification =
dataSource as ISupportInitializeNotification;
if (notification != null && _NotificationInProgress == true)
{
notification.Initialized -= DataSourceInitialized;
_NotificationInProgress = false;
_NotificationAutogen = false;
}
}
#endregion
#region DataSourceInitialized
private void DataSourceInitialized(object sender, EventArgs e)
{
ISupportInitializeNotification dataSource =
_Chart.DataSource as ISupportInitializeNotification;
if (dataSource != null)
{
_NotificationInProgress = false;
dataSource.Initialized -= DataSourceInitialized;
CurrencyManager =
_ChartControl.BindingContext[dataSource] as CurrencyManager;
if (dataSource is DataTable)
ProcessAddDataTable((DataTable)dataSource, _NotificationAutogen);
else
ProcessAddList(dataSource, _NotificationAutogen);
}
}
#endregion
#region GetPdc
private PropertyDescriptorCollection GetPdc(object dataItem)
{
if (_Chart.EnableDiscreteBoundItems == false)
return (_Pdc);
if (dataItem != null)
return (TypeDescriptor.GetProperties(dataItem.GetType()));
return (null);
}
#endregion
#region FindPropertyDescriptor
private PropertyDescriptor FindPropertyDescriptor(
PropertyDescriptorCollection pdc, string name)
{
if (pdc != null)
{
foreach (PropertyDescriptor pd in pdc)
{
if (pd.Name.Equals(name) == true)
return (pd);
}
}
return (null);
}
#endregion
#region FindChartSeries
private BaseSeries FindChartSeries(string name)
{
ChartBaseSeriesCollection baseSeries = _Chart.BaseSeries;
foreach (BaseSeries series in baseSeries)
{
if (name.Equals(series.Name) == true)
return (series);
}
return (null);
}
#endregion
#region LoadSeriesData
internal void LoadSeriesData(BaseSeries series)
{
if (_BaseDataSource is DataSet)
LoadDataSetTable((DataSet)_BaseDataSource, _BaseDataMember, series);
else if (_BaseDataSource is DataTable)
LoadDataTableSeriesData((DataTable)_BaseDataSource, series);
else
LoadListSeriesData(series);
}
#region LoadDataSetTable
internal void LoadDataSetTable(DataSet dataSet, string dataMember, BaseSeries series)
{
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (string.IsNullOrEmpty(dataMember) == false)
LoadDataTableSeriesData(dataSet.Tables[dataMember], series);
}
#endregion
#region LoadDataTableSeriesData
private void LoadDataTableSeriesData(DataTable dt, BaseSeries series)
{
DataColumn dtSeries = FindDataColumn(dt, series.DataPropertyNameSeries);
DataColumn dtNameX = FindDataColumn(dt, series.DataPropertyNameX);
if (dtNameX == null)
throw new Exception("DataPropertyNameX (" + series.DataPropertyNameX + ") not present in DataTable.");
DataColumn[] dtNamesY =
new DataColumn[series.DataPropertyNamesY.Count];
for (int i = 0; i < series.DataPropertyNamesY.Count; i++)
{
string name = series.DataPropertyNamesY[i];
dtNamesY[i] = FindDataColumn(dt, name);
if (dtNamesY[i] == null)
throw new Exception("DataPropertyNameY (" + name + ") not present in DataTable.");
}
if (dtSeries == null)
LoadDataTableSeriesDataSingle(series, dt, dtNameX, dtNamesY);
else
LoadDataTableSeriesDataMultiple(series, dt, dtSeries, dtNameX, dtNamesY);
_ChartControl.DoSeriesDataBindingCompleteEvent(_Chart, series, dt);
}
#region LoadDataTableSeriesDataSingle
private void LoadDataTableSeriesDataSingle(
BaseSeries series, DataTable dt, DataColumn dtNameX, DataColumn[] dtNamesY)
{
for (int i = 0; i < CurrencyManager.Count; i++)
{
DataRowView view = CurrencyManager.List[i] as DataRowView;
if (view != null)
AddDataTableSeriesData(series, dt, dtNameX, dtNamesY, view);
}
}
#endregion
#region LoadDataTableSeriesDataMultiple
private void LoadDataTableSeriesDataMultiple(BaseSeries series,
DataTable dt, DataColumn dtSeries, DataColumn dtNameX, DataColumn[] dtNamesY)
{
for (int i = 0; i < CurrencyManager.Count; i++)
{
DataRowView view = CurrencyManager.List[i] as DataRowView;
if (view != null)
{
object seriesKey = view.Row.ItemArray[dtSeries.Ordinal];
if (seriesKey == series.SeriesKey || seriesKey.Equals(series.SeriesKey))
AddDataTableSeriesData(series, dt, dtNameX, dtNamesY, view);
}
}
}
#endregion
#region AddDataTableSeriesData
private void AddDataTableSeriesData(BaseSeries series,
DataTable dt, DataColumn dtNameX, DataColumn[] dtNamesY, DataRowView view)
{
object valueX = view.Row.ItemArray[dtNameX.Ordinal];
object[] valuesY = new object[dtNamesY.Length];
for (int i = 0; i < dtNamesY.Length; i++)
{
DataColumn dtcol = dtNamesY[i];
valuesY[i] = view.Row.ItemArray[dtcol.Ordinal];
}
series.AddSeriesPoint(valueX, valuesY, view);
}
#endregion
#endregion
#region LoadListSeriesData
private void LoadListSeriesData(BaseSeries series)
{
object source = _BaseDataSource;
PropertyDescriptor pdSeries = FindListPd(series.DataPropertyNameSeries);
PropertyDescriptor pdNameX = FindListPd(series.DataPropertyNameX);
if (pdNameX == null)
throw new Exception("DataPropertyNameX (" + series.DataPropertyNameX + ") not present.");
PropertyDescriptor[] pdNamesY =
new PropertyDescriptor[series.DataPropertyNamesY.Count];
for (int i = 0; i < series.DataPropertyNamesY.Count; i++)
{
string name = series.DataPropertyNamesY[i];
pdNamesY[i] = FindListPd(name);
if (pdNamesY[i] == null)
throw new Exception("DataPropertyNameY (" + name + ") not present.");
}
if (pdSeries == null)
LoadListSeriesDataSingle(series, source, pdNameX, pdNamesY);
else
LoadListSeriesDataMultiple(series, source, pdSeries, pdNameX, pdNamesY);
_ChartControl.DoSeriesDataBindingCompleteEvent(_Chart, series, source);
}
#region LoadListSeriesDataSingle
private void LoadListSeriesDataSingle(
BaseSeries series, object source, PropertyDescriptor pdNameX, PropertyDescriptor[] pdNamesY)
{
IList list = source as IList;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
object o = list[i];
AddListSeriesData(series, o, pdNameX, pdNamesY);
}
}
}
#endregion
#region LoadListSeriesDataMultiple
private void LoadListSeriesDataMultiple(BaseSeries series,
object source, PropertyDescriptor pdSeries, PropertyDescriptor pgNameX, PropertyDescriptor[] pdNamesY)
{
IList list = source as IList;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
object o = list[i];
object seriesKey = pdSeries.GetValue(o);
if (seriesKey == series.SeriesKey || seriesKey.Equals(series.SeriesKey))
AddListSeriesData(series, o, pgNameX, pdNamesY);
}
}
}
#endregion
#region AddListSeriesData
private void AddListSeriesData(BaseSeries series,
object o, PropertyDescriptor pdNameX, PropertyDescriptor[] pdNamesY)
{
object valueX = pdNameX.GetValue(o);
object[] valuesY = new object[pdNamesY.Length];
for (int i = 0; i < pdNamesY.Length; i++)
valuesY[i] = pdNamesY[i].GetValue(o);
series.AddSeriesPoint(valueX, valuesY, o);
}
#endregion
#endregion
#endregion
#region CurrencyManagerListChanged
void CurrencyManagerListChanged(object sender, ListChangedEventArgs e)
{
if (_CurrencyManager != null)
_Chart.InvalidateLayout();
}
#endregion
#region Dispose
/// <summary>
/// Data Binder Dispose
/// </summary>
public void Dispose()
{
CurrencyManager = null;
}
#endregion
}
}