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 { /// ///ColumnGroupHeaderCollection /// [Editor("DevComponents.SuperGrid.Design.ColumnGroupHeaderCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] public class ColumnGroupHeaderCollection : CustomCollection { #region Events #region HeaderMarkupLinkClick internal event EventHandler GroupHeaderMarkupLinkClick; #endregion #endregion #region Private variables private object _Parent; #endregion #region Public properties #region Name indexer /// /// Name indexer /// /// /// [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 /// /// Parent /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object Parent { get { return (_Parent); } internal set { _Parent = value; } } #endregion #endregion #region OnCollectionChanged /// /// Handles CollectionChange notifications /// /// 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 /// /// Occurs when one of element visual styles has property changes. /// Default implementation invalidates visual appearance of element. /// /// VisualStyle that changed. /// Event arguments. protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e) { OnPropertyChanged(e); } #endregion #region INotifyPropertyChanged Members /// /// Default PropertyChanged processing /// /// /// invalidate protected void OnPropertyChangedEx(string s, VisualChangeType changeType) { OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); } #endregion } /// ///Column GroupHeader /// public class ColumnGroupHeader : INotifyPropertyChanged, IDisposable { #region Events #region HeaderMarkupLinkClick internal event EventHandler 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 /// ///ColumnGroupHeader /// public ColumnGroupHeader() { AllowSelection = true; Visible = true; } #region Public properties #region AllowSelection /// /// Gets or sets whether the element can be selected /// [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 /// /// Gets or sets whether Group Header color properties /// (ie. Background and TextColor) are automatically /// applied to group Column Headers /// [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 /// ///The collection the item is contained within /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ColumnGroupHeaderCollection Collection { get { return (_Collection); } internal set { _Collection = value; } } #endregion #region DisplayCount /// /// Gets the count of displayed columns /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int DisplayCount { get { return (_EndDisplayIndex - _StartDisplayIndex + 1); } } #endregion #region EnableHeaderMarkup /// /// Gets or sets whether text-markup support is enabled for the HeaderText /// [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 /// /// Gets or sets the end column display index /// [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 /// ///Gets or sets the GroupHeaders contained under the given header /// [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 /// /// Gets or sets the visual styles assigned to the Column Header /// [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 /// /// Gets or sets the Header Text /// [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 /// ///Returns whether the given GroupHeader is ReadOnly (ie. all ///visible columns/headers it encompasses must be ReadOnly) /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsReadOnly { get { GridColumnHeader gch = GetColumnHeader(); if (gch != null) return (gch.IsGroupHeaderReadOnly(this)); return (false); } } #endregion #region IsSelected /// ///Returns whether the given GroupHeader is selected (ie. all ///visible columns/headers it encompasses must be selected) /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsSelected { get { GridColumnHeader gch = GetColumnHeader(); if (gch != null) return (gch.IsGroupHeaderSelected(this)); return (false); } } #endregion #region MinRowHeight /// /// Gets or sets the minimum height of the Header row /// [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 /// /// Gets or sets the GroupHeader Name /// [DefaultValue(null)] [Description("Indicates the GroupHeader Name")] public string Name { get { return (_Name); } set { _Name = value; } } #endregion #region Parent /// ///The Parent the item /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object Parent { get { if (_Collection != null) return (_Collection.Parent); return (null); } } #endregion #region RowHeight /// /// Gets or sets the fixed height of the header /// [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 /// /// Gets or sets whether the column headers are shown /// [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 /// /// Gets or sets the start column display index /// [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 /// /// Gets or sets the ToolTip text for the sub header. /// [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 /// /// Get or sets whether the item is visible /// [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; } } } /// /// Occurs when a header text markup link is clicked /// protected virtual void HeaderTextMarkupLinkClick(object sender, EventArgs e) { if (GroupHeaderMarkupLinkClick != null) { HyperLink link = (HyperLink)sender; GroupHeaderMarkupLinkClickEventArgs ev = new GroupHeaderMarkupLinkClickEventArgs(this, link); GroupHeaderMarkupLinkClick(this, ev); } } /// /// Gets plain Header text without text-markup (if text-markup is used in Text) /// [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 /// /// Occurs when one of element visual styles has property changes. /// Default implementation invalidates visual appearance of element. /// /// VisualStyle that changed. /// Event arguments. protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e) { OnPropertyChanged(e); } #endregion #region INotifyPropertyChanged Members /// /// Occurs when property value has changed. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Raises the PropertyChanged event. /// /// Event arguments protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { PropertyChangedEventHandler eh = PropertyChanged; if (eh != null) eh(this, e); } /// /// Default PropertyChanged processing /// /// protected void OnPropertyChanged(string s) { if (PropertyChanged != null) OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); } /// /// Default PropertyChanged processing /// /// /// invalidate 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 /// /// Dispose /// public void Dispose() { if (_HeaderTextMarkup != null) { _HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick; _HeaderTextMarkup = null; } } #endregion } #region EventArgs #region GroupHeaderMarkupLinkClickEventArgs /// /// GroupHeaderMarkupLinkClickEventArgs /// internal class GroupHeaderMarkupLinkClickEventArgs : EventArgs { #region Private variables private ColumnGroupHeader _GroupHeader; private HyperLink _HyperLink; #endregion /// /// GroupHeaderMarkupLinkClickEventArgs /// /// /// public GroupHeaderMarkupLinkClickEventArgs(ColumnGroupHeader groupHeader, HyperLink hyperLink) { _GroupHeader = groupHeader; _HyperLink = hyperLink; } #region Public properties /// /// Gets the associated GroupHeader /// public ColumnGroupHeader GroupHeader { get { return (_GroupHeader); } } /// /// Gets the associated HyperLink /// public HyperLink HyperLink { get { return (_HyperLink); } } #endregion } #endregion #endregion }