/* * 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 } }