using System; using System.ComponentModel; namespace DevComponents.DotNetBar.Charts.Style { /// /// VisualStyles /// [TypeConverter(typeof(VisualStylesConverter))] public class VisualStyles : IDisposable, INotifyPropertyChanged, IProcessSerialElement where T : BaseVisualStyle, new() { #region Private variables private T[] _Styles; #endregion /// /// Constructor /// public VisualStyles() { _Styles = new T[Enum.GetValues(typeof(StyleType)).Length - 1]; } #region Public properties #region Indexer /// /// Gets or sets the visual style /// assigned to the element. Default value is null. /// [DefaultValue(null), Category("Style")] [Description("Indicates visual style assigned to the element")] public T this[StyleType e] { get { int n = StyleIndex(e); return (GetStyle(n)); } set { int n = StyleIndex(e); SetStyle(n, value); } } #endregion #region Default /// /// The normal, default style /// [Description("Style to use for normal, default items")] [TypeConverter(typeof(VisualStylesConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public T Default { get { return (GetStyle((int) StyleType.Default)); } set { SetStyle((int) StyleType.Default, value); } } #endregion #region MouseOver /// /// MouseOver /// [Description("Style to use when the Mouse is over an item")] [TypeConverter(typeof(VisualStylesConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public T MouseOver { get { return (GetStyle((int)StyleType.MouseOver)); } set { SetStyle((int)StyleType.MouseOver, value); } } #endregion #region Selected /// /// Selected /// [Description("Style to use when the item is selected")] [TypeConverter(typeof(VisualStylesConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public T Selected { get { return (GetStyle((int)StyleType.Selected)); } set { SetStyle((int)StyleType.Selected, value); } } #endregion #region SelectedMouseOver /// /// MouseOver /// [Description("Style to use when the item is selected and the Mouse is over it")] [TypeConverter(typeof(VisualStylesConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public T SelectedMouseOver { get { return (GetStyle((int)StyleType.SelectedMouseOver)); } set { SetStyle((int)StyleType.SelectedMouseOver, value); } } #endregion #region Styles /// /// Styles array /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public T[] Styles { get { return (_Styles); } } #endregion #region IsEmpty /// /// Gets whether the style collection is logically Empty. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Description("Gets whether the style collection is logically Empty.")] public bool IsEmpty { get { for (int i = 0; i < Styles.Length; i++) { T vstyle = Styles[i]; if (vstyle != null && vstyle.IsEmpty == false) return (false); } return (true); } } #endregion #endregion #region Count internal int Count { get { return (_Styles.Length); } } #endregion #region GetStyle internal T GetStyle(int n) { if (_Styles[n] == null) { _Styles[n] = new T(); OnStyleChangeHandler(null, _Styles[n]); } return (_Styles[n]); } #endregion #region SetStyle internal void SetStyle(int n, T value) { if (_Styles[n] != value) { T oldValue = _Styles[n]; _Styles[n] = value; OnStyleChanged(Enum.GetName(typeof(StyleType), n), oldValue, value); } } #endregion #region GetSerialData internal SerialElementCollection GetSerialData(string serialName) { if (IsEmpty == false) { SerialElementCollection sec = new SerialElementCollection(); if (serialName != null) { if (serialName.Equals("") == true) { serialName = this.ToString(); serialName = serialName.Substring(serialName.LastIndexOf('.') + 1); } sec.AddStartElement(serialName); } string[] enums = Enum.GetNames(typeof(StyleType)); for (int i = 0; i < Styles.Length; i++) { T vstyle = Styles[i]; if (vstyle != null && vstyle.IsEmpty == false) { sec.AddStartElement(enums[i]); sec.AddElement(vstyle.GetSerialData(null)); sec.AddEndElement(enums[i]); } } if (serialName != null) sec.AddEndElement(serialName); return (sec); } return (null); } #endregion #region PutSerialData #region ProcessValue void IProcessSerialElement.ProcessValue(SerialElement se) { throw new Exception("Unknown Serial Value (" + se.Name + ")"); } #endregion #region ProcessCollection void IProcessSerialElement.ProcessCollection(SerialElement se) { switch (se.Name) { case "Default": se.Sec.PutSerialData(Default); break; case "MouseOver": se.Sec.PutSerialData(MouseOver); break; case "Selected": se.Sec.PutSerialData(Selected); break; case "SelectedMouseOver": se.Sec.PutSerialData(SelectedMouseOver); break; default: throw new Exception("Unknown Serial Collection (" + se.Name + ")"); } } #endregion #endregion #region OnStyleChanged private void OnStyleChanged( string property, T oldValue, T newValue) { OnStyleChangeHandler(oldValue, newValue); OnPropertyChanged(new VisualPropertyChangedEventArgs(property)); } #endregion #region StyleIndex internal int StyleIndex(Enum e) { int n = ((IConvertible)e).ToInt32(null); if (n < 0 || n > _Styles.Length) throw new Exception("Invalid Style indexer"); return (n); } #endregion #region IsValid internal T Style(Enum e) { int n = ((IConvertible) e).ToInt32(null); if (n < 0 || n > _Styles.Length) throw new Exception("Invalid Style indexer"); return (_Styles[n]); } #endregion #region GetStyleType internal StyleType GetStyleType(StyleState state) { switch (state) { case StyleState.MouseOver: return (StyleType.MouseOver); case StyleState.Selected: return (StyleType.Selected); case StyleState.Selected | StyleState.MouseOver: return (StyleType.SelectedMouseOver); default: return (StyleType.Default); } } #endregion #region Style support routines #region StyleVisualChangeHandler private void OnStyleChangeHandler(T oldValue, T newValue) { if (oldValue != null) oldValue.PropertyChanged -= StyleChanged; if (newValue != null) newValue.PropertyChanged += StyleChanged; } #endregion #region StyleChanged /// /// 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 StyleChanged(object sender, PropertyChangedEventArgs e) { OnPropertyChanged(e); } #endregion #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); } #endregion #region IDisposable /// /// Dispose /// public void Dispose() { for (int i = 0; i < _Styles.Length; i++) { T style = _Styles[i]; if (style != null) { SetStyle(i, null); style.Dispose(); } } _Styles = null; } #endregion } }