/*
* 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 .
*
* 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
{
///
/// A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView).
///
///
/// This listview keeps itself in sync with its source datatable by listening for change events.
/// 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 to false.
/// These generated columns will be only the simplest view of the world, and would look more interesting with a few delegates installed.
/// This listview will also automatically generate missing aspect getters to fetch the values from the data view.
/// 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.
/// 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.
///
public class DataListView : ObjectListView
{
///
/// Make a DataListView
///
public DataListView()
{
this.Adapter = new DataSourceAdapter(this);
}
#region Public Properties
///
/// Gets or sets whether or not columns will be automatically generated to show the
/// columns when the DataSource is set.
///
/// This must be set before the DataSource is set. It has no effect afterwards.
[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; }
}
///
/// Get or set the DataSource that will be displayed in this list view.
///
/// The DataSource should implement either , ,
/// or . Some common examples are the following types of objects:
///
///
///
///
///
///
///
/// When binding to a list container (i.e. one that implements the
/// interface, such as )
/// you must also set the property in order
/// to identify which particular list you would like to display. You
/// may also set the property even when
/// DataSource refers to a list, since can
/// also be used to navigate relations between lists.
/// When a DataSource is set, the control will create OLVColumns to show any
/// data source columns that are not already shown.
/// If the DataSource is changed, you will have to remove any previously
/// created columns, since they will be configured for the previous DataSource.
/// .
///
[Category("Data"),
TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")]
public virtual Object DataSource
{
get { return this.Adapter.DataSource; }
set { this.Adapter.DataSource = value; }
}
///
/// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data.
///
/// If the data source is not a DataSet or DataViewManager, this property has no effect
[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
///
/// Gets or sets the DataSourceAdaptor that does the bulk of the work needed
/// for data binding.
///
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
///
/// Add the given collection of model objects to this control.
///
/// A collection of model objects
/// 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.
public override void AddObjects(ICollection modelObjects)
{
}
///
/// Remove the given collection of model objects from this control.
///
/// 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.
public override void RemoveObjects(ICollection modelObjects)
{
}
#endregion
#region Event Handlers
///
/// Handles parent binding context changes
///
/// Unused EventArgs.
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
}
}