/*
* Copyright © 2005, Mathew Hall
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using XPTable.Events;
using XPTable.Models;
namespace XPTable.Models.Design
{
///
/// Provides a user interface that can edit collections of Columns
/// at design time
///
public class ColumnCollectionEditor : HelpfulCollectionEditor
{
#region Class Data
///
/// The ColumnCollection being edited
///
private ColumnCollection columns;
///
/// Preview table
///
private Table previewTable;
///
/// ColumnModel for the preview table
///
private ColumnModel previewColumnModel;
///
/// TableModel for the preview table
///
private TableModel previewTableModel;
///
///
///
private Label previewLabel;
#endregion
#region Constructor
///
/// Initializes a new instance of the ColumnCollectionEditor class
/// using the specified collection type
///
/// The type of the collection for this editor to edit
public ColumnCollectionEditor(Type type) : base(type)
{
this.columns = null;
this.previewColumnModel = new ColumnModel();
this.previewColumnModel.Columns.Add(new TextColumn("Column", 116));
this.previewTableModel = new TableModel();
this.previewTableModel.Rows.Add(new Row());
Cell cell = new Cell();
cell.Editable = false;
cell.ToolTipText = "This is a Cell ToolTip";
this.previewTableModel.Rows[0].Cells.Add(cell);
this.previewTableModel.RowHeight = 20;
this.previewTable = new Table();
this.previewTable.Preview = true;
this.previewTable.Size = new Size(120, 274);
this.previewTable.Location = new Point(246, 24);
this.previewTable.GridLines = GridLines.Both;
this.previewTable.TabStop = false;
this.previewTable.EnableToolTips = true;
this.previewTable.ColumnModel = this.previewColumnModel;
this.previewTable.TableModel = this.previewTableModel;
this.previewLabel = new Label();
this.previewLabel.Text = "Preview:";
this.previewLabel.Size = new Size(140, 16);
this.previewLabel.Location = new Point(247, 8);
}
#endregion
#region Methods
///
/// Edits the value of the specified object using the specified
/// service provider and context
///
/// An ITypeDescriptorContext that can be
/// used to gain additional context information
/// A service provider object through which
/// editing services can be obtained
/// The object to edit the value of
/// The new value of the object. If the value of the
/// object has not changed, this should return the same object
/// it was passed
public override object EditValue(ITypeDescriptorContext context, IServiceProvider isp, object value)
{
this.columns = (ColumnCollection) value;
// for some reason (might be beacause Column is an
// abstract class) the table doesn't get redrawn
// when a columns property changes, but we can get
// around that by subscribing to the columns
// PropertyChange event and passing the message on
// to the table ourselves. we need to do this for
// all the existing columns in the collection
for (int i=0; i
/// Gets the data types that this collection editor can contain
///
/// An array of data types that this collection can contain
protected override Type[] CreateNewItemTypes()
{
return new Type[] {typeof(TextColumn),
typeof(ButtonColumn),
typeof(CheckBoxColumn),
typeof(ColorColumn),
typeof(ComboBoxColumn),
typeof(DateTimeColumn),
typeof(ImageColumn),
typeof(NumberColumn),
typeof(ProgressBarColumn)};
}
///
/// Creates a new instance of the specified collection item type
///
/// The type of item to create
/// A new instance of the specified object
protected override object CreateInstance(Type itemType)
{
Column column = (Column) base.CreateInstance(itemType);
// newly created items aren't added to the collection
// until editing has finished. we'd like the newly
// created column to show up in the table immediately
// so we'll add it to the ColumnCollection now
this.columns.Add(column);
// for some reason (might be beacause Column is an
// abstract class) the table doesn't get redrawn
// when a columns property changes, but we can get
// around that by subscribing to the columns
// PropertyChange event and passing the message on
// to the table ourselves
column.PropertyChanged += new XPTable.Events.ColumnEventHandler(column_PropertyChanged);
return column;
}
///
/// Destroys the specified instance of the object
///
/// The object to destroy
protected override void DestroyInstance(object instance)
{
if (instance != null && instance is Column)
{
Column column = (Column) instance;
// the specified column is about to be destroyed
// so we need to remove it from the ColumnCollection first
this.columns.Remove(column);
column.PropertyChanged -= new XPTable.Events.ColumnEventHandler(column_PropertyChanged);
}
base.DestroyInstance(instance);
}
///
/// Creates a new form to display and edit the current collection
///
/// An instance of CollectionEditor.CollectionForm to provide
/// as the user interface for editing the collection
protected override CollectionEditor.CollectionForm CreateCollectionForm()
{
CollectionEditor.CollectionForm editor = base.CreateCollectionForm();
editor.Width += 140;
foreach (Control control in editor.Controls)
{
if (control.Name.Equals("propertiesLabel"))
{
control.Location = new Point(control.Left + 140, control.Top);
}
//
if (control is PropertyGrid)
{
PropertyGrid grid = (PropertyGrid) control;
grid.SelectedObjectsChanged += new EventHandler(this.PropertyGrid_SelectedObjectsChanged);
grid.Location = new Point(grid.Left + 140, grid.Top);
grid.Width -= 140;
}
}
editor.Controls.Add(this.previewLabel);
editor.Controls.Add(this.previewTable);
return editor;
}
#endregion
#region Events
///
/// Handler for the PropertyGrid's SelectedObjectsChanged event
///
/// The object that raised the event
/// An EventArgs that contains the event data
protected void PropertyGrid_SelectedObjectsChanged(object sender, EventArgs e)
{
object[] objects = ((PropertyGrid) sender).SelectedObjects;
this.previewColumnModel.Columns.Clear();
if (objects.Length == 1)
{
Column column = (Column) objects[0];
Cell cell = this.previewTableModel[0, 0];
if (column is ButtonColumn)
{
cell.Text = "Button";
cell.Data = null;
}
else if (column is CheckBoxColumn)
{
cell.Text = "Checkbox";
cell.Data = null;
cell.Checked = true;
}
else if (column is ColorColumn)
{
cell.Text = null;
cell.Data = Color.Red;
}
else if (column is ComboBoxColumn)
{
cell.Text = "ComboBox";
cell.Data = null;
}
else if (column is DateTimeColumn)
{
cell.Text = null;
cell.Data = DateTime.Now;
}
else if (column is ImageColumn)
{
cell.Text = "Image";
cell.Data = null;
}
else if (column is NumberColumn || column is ProgressBarColumn)
{
cell.Text = null;
cell.Data = 50;
}
else //if (column is TextColumn)
{
cell.Text = "Text";
cell.Data = null;
}
this.previewColumnModel.Columns.Add(column);
}
this.previewTable.Invalidate();
}
///
/// Handler for a Column's PropertyChanged event
///
/// The object that raised the event
/// A ColumnEventArgs that contains the event data
private void column_PropertyChanged(object sender, ColumnEventArgs e)
{
this.columns.ColumnModel.OnColumnPropertyChanged(e);
}
#endregion
}
}