1122 lines
30 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using DevComponents.DotNetBar.SuperGrid.Primitives;
using DevComponents.DotNetBar.SuperGrid.Style;
using DevComponents.SuperGrid.TextMarkup;
namespace DevComponents.DotNetBar.SuperGrid
{
///<summary>
///ColumnGroupHeaderCollection
///</summary>
[Editor("DevComponents.SuperGrid.Design.ColumnGroupHeaderCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))]
public class ColumnGroupHeaderCollection : CustomCollection<ColumnGroupHeader>
{
#region Events
#region HeaderMarkupLinkClick
internal event EventHandler<GroupHeaderMarkupLinkClickEventArgs> GroupHeaderMarkupLinkClick;
#endregion
#endregion
#region Private variables
private object _Parent;
#endregion
#region Public properties
#region Name indexer
///<summary>
/// Name indexer
///</summary>
///<param name="name"></param>
///<exception cref="Exception"></exception>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ColumnGroupHeader this[string name]
{
get
{
int index = FindIndexByName(name);
return (index >= 0 ? this[index] : null);
}
set
{
int index = FindIndexByName(name);
if (index < 0)
throw new Exception("Column Name not defined (" + name + ").");
Items[index] = value;
}
}
#region FindIndexByName
private int FindIndexByName(string name)
{
for (int i = 0; i < Items.Count; i++)
{
ColumnGroupHeader item = Items[i];
if (name != null)
name = name.ToUpper();
if (item.Name != null && item.Name.ToUpper().Equals(name))
return (i);
}
return (-1);
}
#endregion
#endregion
#region Parent
///<summary>
/// Parent
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Parent
{
get { return (_Parent); }
internal set { _Parent = value; }
}
#endregion
#endregion
#region OnCollectionChanged
/// <summary>
/// Handles CollectionChange notifications
/// </summary>
/// <param name="e"></param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (INotifyPropertyChanged newValue in e.NewItems)
{
ItemChangeHandler(null, newValue);
PropertyChangeHandler(null, newValue);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (INotifyPropertyChanged oldValue in e.OldItems)
{
ItemChangeHandler(null, oldValue);
PropertyChangeHandler(null, oldValue);
}
break;
case NotifyCollectionChangedAction.Replace:
for (int i = 0; i < e.OldItems.Count; i++)
{
ItemChangeHandler(e.OldItems[i], e.NewItems[i]);
PropertyChangeHandler((INotifyPropertyChanged)e.OldItems[i],
(INotifyPropertyChanged)e.NewItems[i]);
}
break;
case NotifyCollectionChangedAction.Reset:
for (int i = 0; i < Items.Count; i++)
{
ItemChangeHandler(Items[i], null);
PropertyChangeHandler(Items[i], null);
}
break;
}
base.OnCollectionChanged(e);
}
#endregion
#region ItemChangeHandler
private void ItemChangeHandler(object oldValue, object newValue)
{
ColumnGroupHeader cgh = oldValue as ColumnGroupHeader;
if (cgh != null)
{
cgh.Collection = null;
cgh.GroupHeaderMarkupLinkClick -= CGroupHeaderMarkupLinkClick;
}
cgh = newValue as ColumnGroupHeader;
if (cgh != null)
{
cgh.Collection = this;
cgh.GroupHeaderMarkupLinkClick += CGroupHeaderMarkupLinkClick;
}
}
#endregion
#region CGroupHeaderMarkupLinkClick
void CGroupHeaderMarkupLinkClick(object sender, GroupHeaderMarkupLinkClickEventArgs e)
{
if (GroupHeaderMarkupLinkClick != null)
GroupHeaderMarkupLinkClick(sender, e);
}
#endregion
#region PropertyChangeHandler
private void PropertyChangeHandler(
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
{
if (oldValue != null)
oldValue.PropertyChanged -= PropertyValueChanged;
if (newValue != null)
newValue.PropertyChanged += PropertyValueChanged;
}
#endregion
#region PropertyValueChanged
/// <summary>
/// Occurs when one of element visual styles has property changes.
/// Default implementation invalidates visual appearance of element.
/// </summary>
/// <param name="sender">VisualStyle that changed.</param>
/// <param name="e">Event arguments.</param>
protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Default PropertyChanged processing
/// </summary>
/// <param name="s"></param>
/// <param name="changeType">invalidate</param>
protected void OnPropertyChangedEx(string s, VisualChangeType changeType)
{
OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType));
}
#endregion
}
///<summary>
///Column GroupHeader
///</summary>
public class ColumnGroupHeader : INotifyPropertyChanged, IDisposable
{
#region Events
#region HeaderMarkupLinkClick
internal event EventHandler<GroupHeaderMarkupLinkClickEventArgs> GroupHeaderMarkupLinkClick;
#endregion
#endregion
#region Private variables
private int _StartDisplayIndex = -1;
private int _EndDisplayIndex = -1;
private int _RowHeight;
private int _MinRowHeight;
private int _StyleUpdateCount;
private ColumnHeaderVisualStyles _HeaderStyles;
private ColumnHeaderVisualStyles _EffectiveStyles;
private ColumnGroupHeaderCollection _Collection;
private ColumnGroupHeaderCollection _GroupHeaders;
private string _Name;
private string _ToolTip;
private string _HeaderText;
private BodyElement _HeaderTextMarkup;
private Size _Size;
private Size _ContentSize;
private Size _HeaderTextSize;
private Rectangle _BoundsRelative;
private Shs _States;
private Tbool _ShowColumnHeaders = Tbool.NotSet;
private Tbool _AutoApplyGroupColors = Tbool.NotSet;
#endregion
///<summary>
///ColumnGroupHeader
///</summary>
public ColumnGroupHeader()
{
AllowSelection = true;
Visible = true;
}
#region Public properties
#region AllowSelection
/// <summary>
/// Gets or sets whether the element can be selected
/// </summary>
[DefaultValue(true), Category("Behavior")]
[Description("Indicates whether the element can be selected")]
public bool AllowSelection
{
get { return (TestState(Shs.AllowSelection)); }
set
{
if (AllowSelection != value)
{
SetState(Shs.AllowSelection, value);
OnPropertyChangedEx("AllowSelection", VisualChangeType.Render);
}
}
}
#endregion
#region AutoApplyGroupColors
///<summary>
/// Gets or sets whether Group Header color properties
/// (ie. Background and TextColor) are automatically
/// applied to group Column Headers
///</summary>
[DefaultValue(Tbool.NotSet), Category("Appearance")]
[Description("Indicates whether Group Header color properties (ie. Background and TextColor) are automatically applied to group Column Headers.")]
public Tbool AutoApplyGroupColors
{
get { return (_AutoApplyGroupColors); }
set
{
if (_AutoApplyGroupColors != value)
{
_AutoApplyGroupColors = value;
OnPropertyChangedEx("AutoApplyGroupColors", VisualChangeType.Render);
}
}
}
#endregion
#region Collection
///<summary>
///The collection the item is contained within
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ColumnGroupHeaderCollection Collection
{
get { return (_Collection); }
internal set { _Collection = value; }
}
#endregion
#region DisplayCount
///<summary>
/// Gets the count of displayed columns
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int DisplayCount
{
get { return (_EndDisplayIndex - _StartDisplayIndex + 1); }
}
#endregion
#region EnableHeaderMarkup
/// <summary>
/// Gets or sets whether text-markup support is enabled for the HeaderText
/// </summary>
[DefaultValue(false), Category("Appearance")]
[Description("Indicates whether text-markup support is enabled for the HeaderText.")]
public bool EnableHeaderMarkup
{
get { return (TestState(Shs.EnableHeaderMarkup)); }
set
{
if (EnableHeaderMarkup != value)
{
SetState(Shs.EnableHeaderMarkup, value);
MarkupHeaderTextChanged();
OnPropertyChangedEx("EnableHeaderMarkup", VisualChangeType.Layout);
}
}
}
#endregion
#region EndDisplayIndex
///<summary>
/// Gets or sets the end column display index
///</summary>
[DefaultValue(0), Category("Appearance")]
[Description("Indicates the end column display index (inclusive)")]
public int EndDisplayIndex
{
get { return ((_EndDisplayIndex < 0) ? 0 : _EndDisplayIndex); }
set
{
if (_EndDisplayIndex != value)
{
_EndDisplayIndex = value;
OnPropertyChangedEx("EndDisplayIndex", VisualChangeType.Layout);
}
}
}
#endregion
#region GroupHeaders
///<summary>
///Gets or sets the GroupHeaders contained under the given header
///</summary>
[DefaultValue(null), Category("Appearance")]
[Description("Indicates the GroupHeaders contained under the given header.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnGroupHeaderCollection GroupHeaders
{
get
{
if (_GroupHeaders == null)
{
_GroupHeaders = new ColumnGroupHeaderCollection();
_GroupHeaders.Parent = this;
PropertyChangeHandler(null, _GroupHeaders);
GroupCollectionChangeHandler(null, _GroupHeaders);
}
return (_GroupHeaders);
}
set
{
if (_GroupHeaders != value)
{
PropertyChangeHandler(_GroupHeaders, value);
GroupCollectionChangeHandler(_GroupHeaders, value);
_GroupHeaders = value;
OnPropertyChangedEx("GroupHeaders", VisualChangeType.Layout);
}
}
}
#region _GroupHeaders
void GroupHeadersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ColumnGroupHeaderCollection cgc = sender as ColumnGroupHeaderCollection;
if (cgc != null)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
ColumnGroupHeader parent = cgc.Parent as ColumnGroupHeader;
if (parent != null)
{
foreach (ColumnGroupHeader cgh in e.NewItems)
{
if (parent._StartDisplayIndex < 0 || cgh.StartDisplayIndex < parent.StartDisplayIndex)
parent.StartDisplayIndex = cgh.StartDisplayIndex;
if (parent._EndDisplayIndex < 0 || cgh.EndDisplayIndex > parent.EndDisplayIndex)
parent.EndDisplayIndex = cgh.EndDisplayIndex;
}
}
}
}
}
#endregion
#endregion
#region HeaderStyles
/// <summary>
/// Gets or sets the visual styles assigned to the Column Header
/// </summary>
[DefaultValue(null), Category("Appearance")]
[Description("Indicates visual style assigned to the Column Header.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnHeaderVisualStyles HeaderStyles
{
get
{
if (_HeaderStyles == null)
{
_HeaderStyles = new ColumnHeaderVisualStyles();
PropertyChangeHandler(null, _HeaderStyles);
}
return (_HeaderStyles);
}
set
{
if (_HeaderStyles != value)
{
PropertyChangeHandler(_HeaderStyles, value);
_HeaderStyles = value;
OnPropertyChangedEx("HeaderStyles", VisualChangeType.Layout);
}
}
}
#endregion
#region HeaderText
///<summary>
/// Gets or sets the Header Text
///</summary>
[DefaultValue(null), Category("Appearance")]
[Description("Indicates the Header Text")]
public string HeaderText
{
get { return (_HeaderText); }
set
{
if (_HeaderText != value)
{
_HeaderText = value;
MarkupHeaderTextChanged();
OnPropertyChangedEx("HeaderText", VisualChangeType.Layout);
}
}
}
#endregion
#region IsReadOnly
///<summary>
///Returns whether the given GroupHeader is ReadOnly (ie. all
///visible columns/headers it encompasses must be ReadOnly)
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsReadOnly
{
get
{
GridColumnHeader gch = GetColumnHeader();
if (gch != null)
return (gch.IsGroupHeaderReadOnly(this));
return (false);
}
}
#endregion
#region IsSelected
///<summary>
///Returns whether the given GroupHeader is selected (ie. all
///visible columns/headers it encompasses must be selected)
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsSelected
{
get
{
GridColumnHeader gch = GetColumnHeader();
if (gch != null)
return (gch.IsGroupHeaderSelected(this));
return (false);
}
}
#endregion
#region MinRowHeight
///<summary>
/// Gets or sets the minimum height of the Header row
///</summary>
[DefaultValue(0), Category("Style")]
[Description("Indicates the minimum height of the ColumnHeader row")]
public int MinRowHeight
{
get { return (_MinRowHeight); }
set
{
if (_MinRowHeight != value)
{
if (value < 0)
throw new Exception("MinRowHeight cannot be negative");
_MinRowHeight = value;
OnPropertyChangedEx("MinRowHeight", VisualChangeType.Layout);
}
}
}
#endregion
#region Name
///<summary>
/// Gets or sets the GroupHeader Name
///</summary>
[DefaultValue(null)]
[Description("Indicates the GroupHeader Name")]
public string Name
{
get { return (_Name); }
set { _Name = value; }
}
#endregion
#region Parent
///<summary>
///The Parent the item
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Parent
{
get
{
if (_Collection != null)
return (_Collection.Parent);
return (null);
}
}
#endregion
#region RowHeight
///<summary>
/// Gets or sets the fixed height of the header
///</summary>
[DefaultValue(0), Category("Appearance")]
[Description("Indicates the fixed height of the header")]
public int RowHeight
{
get { return (_RowHeight); }
set
{
if (_RowHeight != value)
{
_RowHeight = value;
OnPropertyChangedEx("RowHeight", VisualChangeType.Layout);
}
}
}
#endregion
#region ShowColumnHeaders
///<summary>
/// Gets or sets whether the column headers are shown
///</summary>
[DefaultValue(Tbool.NotSet), Category("Appearance")]
[Description("Indicates whether the root column headers are shown.")]
public Tbool ShowColumnHeaders
{
get { return (_ShowColumnHeaders); }
set
{
if (_ShowColumnHeaders != value)
{
_ShowColumnHeaders = value;
OnPropertyChangedEx("ShowColumnHeaders", VisualChangeType.Layout);
}
}
}
#endregion
#region StartDisplayIndex
///<summary>
/// Gets or sets the start column display index
///</summary>
[DefaultValue(-1), Category("Appearance")]
[Description("Indicates the start column index")]
public int StartDisplayIndex
{
get { return ((_StartDisplayIndex < 0) ? 0 : _StartDisplayIndex); }
set
{
if (_StartDisplayIndex != value)
{
_StartDisplayIndex = value;
OnPropertyChangedEx("StartDisplayIndex", VisualChangeType.Layout);
}
}
}
#endregion
#region ToolTip
///<summary>
/// Gets or sets the ToolTip text for the sub header.
///</summary>
[DefaultValue(null), Category("Appearance")]
[Description("Indicates ththe ToolTip text for the sub header.")]
public string ToolTip
{
get { return (_ToolTip); }
set
{
if (_ToolTip != value)
{
_ToolTip = value;
OnPropertyChanged("ToolTip");
}
}
}
#endregion
#region Visible
/// <summary>
/// Get or sets whether the item is visible
/// </summary>
[DefaultValue(true), Category("Appearance")]
[Description("Indicates whether item is visible")]
public bool Visible
{
get { return (TestState(Shs.Visible)); }
set
{
if (Visible != value)
{
SetState(Shs.Visible, value);
OnPropertyChangedEx("Visible", VisualChangeType.Layout);
}
}
}
#endregion
#endregion
#region Internal properties
#region BoundsRelative
// Does not include sub headers
internal Rectangle BoundsRelative
{
get { return (_BoundsRelative); }
set { _BoundsRelative = value; }
}
#endregion
#region ContentSize
internal Size ContentSize
{
get { return (_ContentSize); }
set { _ContentSize = value; }
}
#endregion
#region EffectiveStyles
internal ColumnHeaderVisualStyles EffectiveStyles
{
get { return (_EffectiveStyles); }
set { _EffectiveStyles = value; }
}
#endregion
#region HeaderTextMarkup
internal BodyElement HeaderTextMarkup
{
get { return (_HeaderTextMarkup); }
}
#endregion
#region HeaderTextSize
internal Size HeaderTextSize
{
get { return (_HeaderTextSize); }
set { _HeaderTextSize = value; }
}
#endregion
#region Size
// Includes sub headers
internal Size Size
{
get { return (_Size); }
set { _Size = value; }
}
#endregion
#region StyleUpdateCount
internal int StyleUpdateCount
{
get { return (_StyleUpdateCount); }
set { _StyleUpdateCount = value; }
}
#endregion
#endregion
#region TestState
private bool TestState(Shs state)
{
return ((_States & state) == state);
}
#endregion
#region SetState
private void SetState(Shs state, bool value)
{
if (value == true)
_States |= state;
else
_States &= ~state;
}
#endregion
#region Contains
internal bool Contains(int index)
{
return (index >= StartDisplayIndex && index <= EndDisplayIndex);
}
#endregion
#region GetColumnHeader
private GridColumnHeader GetColumnHeader()
{
object parent = Collection.Parent;
while (parent.GetType() == typeof(ColumnGroupHeader))
parent = ((ColumnGroupHeader)parent).Collection.Parent;
return (parent as GridColumnHeader);
}
#endregion
#region Markup support
private void MarkupHeaderTextChanged()
{
if (_HeaderTextMarkup != null)
_HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick;
_HeaderTextMarkup = null;
if (EnableHeaderMarkup == true)
{
if (MarkupParser.IsMarkup(_HeaderText) == true)
{
_HeaderTextMarkup = MarkupParser.Parse(_HeaderText);
if (_HeaderTextMarkup != null)
_HeaderTextMarkup.HyperLinkClick += HeaderTextMarkupLinkClick;
}
}
}
/// <summary>
/// Occurs when a header text markup link is clicked
/// </summary>
protected virtual void HeaderTextMarkupLinkClick(object sender, EventArgs e)
{
if (GroupHeaderMarkupLinkClick != null)
{
HyperLink link = (HyperLink)sender;
GroupHeaderMarkupLinkClickEventArgs ev =
new GroupHeaderMarkupLinkClickEventArgs(this, link);
GroupHeaderMarkupLinkClick(this, ev);
}
}
/// <summary>
/// Gets plain Header text without text-markup (if text-markup is used in Text)
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public string PlainHeaderText
{
get { return (_HeaderTextMarkup != null ? _HeaderTextMarkup.PlainText : _HeaderText); }
}
#endregion
#region GroupCollectionChangeHandler
private void GroupCollectionChangeHandler(
ColumnGroupHeaderCollection oldValue, ColumnGroupHeaderCollection newValue)
{
if (oldValue != null)
{
oldValue.Parent = null;
oldValue.CollectionChanged -= GroupHeadersCollectionChanged;
}
if (newValue != null)
{
newValue.Parent = this;
newValue.CollectionChanged += GroupHeadersCollectionChanged;
}
}
#endregion
#region PropertyChangeHandler
private void PropertyChangeHandler(
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
{
if (oldValue != null)
oldValue.PropertyChanged -= PropertyValueChanged;
if (newValue != null)
newValue.PropertyChanged += PropertyValueChanged;
}
#endregion
#region PropertyValueChanged
/// <summary>
/// Occurs when one of element visual styles has property changes.
/// Default implementation invalidates visual appearance of element.
/// </summary>
/// <param name="sender">VisualStyle that changed.</param>
/// <param name="e">Event arguments.</param>
protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null)
eh(this, e);
}
/// <summary>
/// Default PropertyChanged processing
/// </summary>
/// <param name="s"></param>
protected void OnPropertyChanged(string s)
{
if (PropertyChanged != null)
OnPropertyChanged(new VisualPropertyChangedEventArgs(s));
}
/// <summary>
/// Default PropertyChanged processing
/// </summary>
/// <param name="s"></param>
/// <param name="changeType">invalidate</param>
protected void OnPropertyChangedEx(string s, VisualChangeType changeType)
{
if (PropertyChanged != null)
OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType));
}
#endregion
#region GroupHeaderStates
[Flags]
private enum Shs
{
AllowSelection = (1 << 0),
EnableHeaderMarkup = (1 << 1),
Visible = (1 << 2),
}
#endregion
#region Dispose
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
if (_HeaderTextMarkup != null)
{
_HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick;
_HeaderTextMarkup = null;
}
}
#endregion
}
#region EventArgs
#region GroupHeaderMarkupLinkClickEventArgs
/// <summary>
/// GroupHeaderMarkupLinkClickEventArgs
/// </summary>
internal class GroupHeaderMarkupLinkClickEventArgs : EventArgs
{
#region Private variables
private ColumnGroupHeader _GroupHeader;
private HyperLink _HyperLink;
#endregion
///<summary>
/// GroupHeaderMarkupLinkClickEventArgs
///</summary>
///<param name="groupHeader"></param>
///<param name="hyperLink"></param>
public GroupHeaderMarkupLinkClickEventArgs(ColumnGroupHeader groupHeader, HyperLink hyperLink)
{
_GroupHeader = groupHeader;
_HyperLink = hyperLink;
}
#region Public properties
/// <summary>
/// Gets the associated GroupHeader
/// </summary>
public ColumnGroupHeader GroupHeader
{
get { return (_GroupHeader); }
}
/// <summary>
/// Gets the associated HyperLink
/// </summary>
public HyperLink HyperLink
{
get { return (_HyperLink); }
}
#endregion
}
#endregion
#endregion
}