200 lines
8.8 KiB
C#
200 lines
8.8 KiB
C#
![]() |
/*
|
||
|
* DataListView - A data-bindable listview
|
||
|
*
|
||
|
* Author: Phillip Piper
|
||
|
* Date: 27/09/2008 9:15 AM
|
||
|
*
|
||
|
* Change log:
|
||
|
* 2011-02-27 JPP - Moved most of the logic to DataSourceAdapter (where it
|
||
|
* can be used by FastDataListView too)
|
||
|
* v2.3
|
||
|
* 2009-01-18 JPP - Boolean columns are now handled as checkboxes
|
||
|
* - Auto-generated columns would fail if the data source was
|
||
|
* reseated, even to the same data source
|
||
|
* v2.0.1
|
||
|
* 2009-01-07 JPP - Made all public and protected methods virtual
|
||
|
* 2008-10-03 JPP - Separated from ObjectListView.cs
|
||
|
*
|
||
|
* Copyright (C) 2006-2014 Phillip Piper
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
* If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
|
||
|
*/
|
||
|
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.ComponentModel;
|
||
|
using System.Data;
|
||
|
using System.Diagnostics;
|
||
|
using System.Drawing.Design;
|
||
|
using System.Windows.Forms;
|
||
|
|
||
|
namespace BrightIdeasSoftware
|
||
|
{
|
||
|
|
||
|
/// <summary>
|
||
|
/// A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView).
|
||
|
/// </summary>
|
||
|
/// <remarks>
|
||
|
/// <para>This listview keeps itself in sync with its source datatable by listening for change events.</para>
|
||
|
/// <para>The DataListView will automatically create columns to show all of the data source's columns/properties, if there is not already
|
||
|
/// a column showing that property. This allows you to define one or two columns in the designer and then have the others generated automatically.
|
||
|
/// If you don't want any column to be auto generated, set <see cref="AutoGenerateColumns"/> to false.
|
||
|
/// These generated columns will be only the simplest view of the world, and would look more interesting with a few delegates installed.</para>
|
||
|
/// <para>This listview will also automatically generate missing aspect getters to fetch the values from the data view.</para>
|
||
|
/// <para>Changing data sources is possible, but error prone. Before changing data sources, the programmer is responsible for modifying/resetting
|
||
|
/// the column collection to be valid for the new data source.</para>
|
||
|
/// <para>Internally, a CurrencyManager controls keeping the data source in-sync with other users of the data source (as per normal .NET
|
||
|
/// behavior). This means that the model objects in the DataListView are DataRowView objects. If you write your own AspectGetters/Setters,
|
||
|
/// they will be given DataRowView objects.</para>
|
||
|
/// </remarks>
|
||
|
public class DataListView : ObjectListView
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Make a DataListView
|
||
|
/// </summary>
|
||
|
public DataListView()
|
||
|
{
|
||
|
this.Adapter = new DataSourceAdapter(this);
|
||
|
}
|
||
|
|
||
|
#region Public Properties
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets whether or not columns will be automatically generated to show the
|
||
|
/// columns when the DataSource is set.
|
||
|
/// </summary>
|
||
|
/// <remarks>This must be set before the DataSource is set. It has no effect afterwards.</remarks>
|
||
|
[Category("Data"),
|
||
|
Description("Should the control automatically generate columns from the DataSource"),
|
||
|
DefaultValue(true)]
|
||
|
public bool AutoGenerateColumns {
|
||
|
get { return this.Adapter.AutoGenerateColumns; }
|
||
|
set { this.Adapter.AutoGenerateColumns = value; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Get or set the DataSource that will be displayed in this list view.
|
||
|
/// </summary>
|
||
|
/// <remarks>The DataSource should implement either <see cref="IList"/>, <see cref="IBindingList"/>,
|
||
|
/// or <see cref="IListSource"/>. Some common examples are the following types of objects:
|
||
|
/// <list type="unordered">
|
||
|
/// <item><description><see cref="DataView"/></description></item>
|
||
|
/// <item><description><see cref="DataTable"/></description></item>
|
||
|
/// <item><description><see cref="DataSet"/></description></item>
|
||
|
/// <item><description><see cref="DataViewManager"/></description></item>
|
||
|
/// <item><description><see cref="BindingSource"/></description></item>
|
||
|
/// </list>
|
||
|
/// <para>When binding to a list container (i.e. one that implements the
|
||
|
/// <see cref="IListSource"/> interface, such as <see cref="DataSet"/>)
|
||
|
/// you must also set the <see cref="DataMember"/> property in order
|
||
|
/// to identify which particular list you would like to display. You
|
||
|
/// may also set the <see cref="DataMember"/> property even when
|
||
|
/// DataSource refers to a list, since <see cref="DataMember"/> can
|
||
|
/// also be used to navigate relations between lists.</para>
|
||
|
/// <para>When a DataSource is set, the control will create OLVColumns to show any
|
||
|
/// data source columns that are not already shown.</para>
|
||
|
/// <para>If the DataSource is changed, you will have to remove any previously
|
||
|
/// created columns, since they will be configured for the previous DataSource.
|
||
|
/// <see cref="ObjectListView.Reset()"/>.</para>
|
||
|
/// </remarks>
|
||
|
[Category("Data"),
|
||
|
TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")]
|
||
|
public virtual Object DataSource
|
||
|
{
|
||
|
get { return this.Adapter.DataSource; }
|
||
|
set { this.Adapter.DataSource = value; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data.
|
||
|
/// </summary>
|
||
|
/// <remarks>If the data source is not a DataSet or DataViewManager, this property has no effect</remarks>
|
||
|
[Category("Data"),
|
||
|
Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor)),
|
||
|
DefaultValue("")]
|
||
|
public virtual string DataMember
|
||
|
{
|
||
|
get { return this.Adapter.DataMember; }
|
||
|
set { this.Adapter.DataMember = value; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Implementation properties
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the DataSourceAdaptor that does the bulk of the work needed
|
||
|
/// for data binding.
|
||
|
/// </summary>
|
||
|
protected DataSourceAdapter Adapter {
|
||
|
get {
|
||
|
Debug.Assert(adapter != null, "Data adapter should not be null");
|
||
|
return adapter;
|
||
|
}
|
||
|
set { adapter = value; }
|
||
|
}
|
||
|
private DataSourceAdapter adapter;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Object manipulations
|
||
|
|
||
|
/// <summary>
|
||
|
/// Add the given collection of model objects to this control.
|
||
|
/// </summary>
|
||
|
/// <param name="modelObjects">A collection of model objects</param>
|
||
|
/// <remarks>This is a no-op for data lists, since the data
|
||
|
/// is controlled by the VirtualListDataSource. Manipulate the data source
|
||
|
/// rather than this view of the data source.</remarks>
|
||
|
public override void AddObjects(ICollection modelObjects)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Remove the given collection of model objects from this control.
|
||
|
/// </summary>
|
||
|
/// <remarks>This is a no-op for data lists, since the data
|
||
|
/// is controlled by the VirtualListDataSource. Manipulate the data source
|
||
|
/// rather than this view of the data source.</remarks>
|
||
|
public override void RemoveObjects(ICollection modelObjects)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Event Handlers
|
||
|
|
||
|
/// <summary>
|
||
|
/// Handles parent binding context changes
|
||
|
/// </summary>
|
||
|
/// <param name="e">Unused EventArgs.</param>
|
||
|
protected override void OnParentBindingContextChanged(EventArgs e)
|
||
|
{
|
||
|
base.OnParentBindingContextChanged(e);
|
||
|
|
||
|
// BindingContext is an ambient property - by default it simply picks
|
||
|
// up the parent control's context (unless something has explicitly
|
||
|
// given us our own). So we must respond to changes in our parent's
|
||
|
// binding context in the same way we would changes to our own
|
||
|
// binding context.
|
||
|
|
||
|
// THINK: Do we need to forward this to the adapter?
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
}
|