#region Disclaimer / License // Copyright (C) 2011, Jackie Ng // http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Windows.Forms.Design.Behavior; using System.Windows.Forms.Design; using System.ComponentModel.Design; using System.Collections; using OSGeo.MapGuide.ObjectModels.SymbolDefinition; using OSGeo.MapGuide.MaestroAPI; using System.Reflection; namespace Maestro.Editors.SymbolDefinition { /// /// A UI control for editing symbol definition settings /// [ToolboxItem(true)] [Designer(typeof(SymbolFieldDesigner))] public partial class SymbolField : UserControl { private class SymbolFieldDesigner : ControlDesigner { public override IList SnapLines { get { /* Code from above */ IList snapLines = base.SnapLines; // *** This will need to be modified to match your user control SymbolField control = Control as SymbolField; if (control == null) { return snapLines; } Control el = control.combo; if (el == null) { return snapLines; } // *** This will need to be modified to match the item in your user control // This is the control in your UC that you want SnapLines for the entire UC IDesigner designer = TypeDescriptor.CreateDesigner( el, typeof(IDesigner)); if (designer == null) { return snapLines; } // *** This will need to be modified to match the item in your user control designer.Initialize(el); using (designer) { ControlDesigner boxDesigner = designer as ControlDesigner; if (boxDesigner == null) { return snapLines; } foreach (SnapLine line in boxDesigner.SnapLines) { if (line.SnapLineType == SnapLineType.Baseline) { // *** This will need to be modified to match the item in your user control snapLines.Add(new SnapLine(SnapLineType.Baseline, line.Offset + el.Top, line.Filter, line.Priority)); break; } } } return snapLines; } } } /// /// A method for presenting symbol parameters for a given symbol field /// /// The sender. public delegate void BrowseEventHandler(SymbolField sender); /// /// Occurs when a request has been made to present symbol parameters for selection /// public event BrowseEventHandler RequestBrowse; /// /// Initializes a new instance of the class. /// public SymbolField() { InitializeComponent(); combo.TextChanged += new EventHandler(combo_TextChanged); } void combo_TextChanged(object sender, EventArgs e) { OnContentChanged(); } /// /// Occurs when [content changed]. /// public event EventHandler ContentChanged; //Important: We need to set this otherwise the Winforms Designer will put you in a world of pain /// /// Gets or sets the content. /// /// /// The content. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string Content { get { return combo.Text; } set { if (combo.Text != value) { combo.Text = value; OnContentChanged(); } } } private void OnContentChanged() { if (_isBinding) return; if (_suppressProperty) return; //Update databound property before raising event if (_boundObjectType != null && _boundObject != null && _boundProperty != null) { try { _suppressUI = true; if (string.IsNullOrEmpty(this.Content)) _boundProperty.SetValue(_boundObject, null, null); else _boundProperty.SetValue(_boundObject, this.Content, null); } finally { _suppressUI = false; } } var handler = this.ContentChanged; if (handler != null) handler(this, EventArgs.Empty); } private string[] _items; //Important: We need to set this otherwise the Winforms Designer will put you in a world of pain /// /// Gets or sets the items. /// /// /// The items. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string[] Items { get { return _items; } set { _items = value; combo.Items.Clear(); foreach (var it in value) { combo.Items.Add(it); } } } private void btnBrowse_Click(object sender, EventArgs e) { var handler = this.RequestBrowse; if (handler != null) handler(this); } //Important: We need to set this otherwise the Winforms Designer will put you in a world of pain //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] //[Description("Indicates the parameter data type(s) that are suitable for this field. Leave empty for all types")] //public DataType[] SupportedDataTypes { get; set; } //Important: We need to set this otherwise the Winforms Designer will put you in a world of pain //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] /// /// Gets or sets the supported enhanced data types. /// /// /// The supported enhanced data types. /// [Description("Indicates the parameter data type(s) that are suitable for this field. Leave empty for all types")] public DataType2[] SupportedEnhancedDataTypes { get; set; } /// /// Gets the items. /// /// /// public static string[] GetItems() { var values = Enum.GetValues(typeof(T)); var items = new string[values.Length]; int i = 0; foreach(var val in values) { items[i] = "'" + val + "'"; i++; } return items; } //This code below attempts to approximate data binding private bool _suppressUI = false; //Used to prevent a stack overflow due to a continuous UI -> Property -> UI -> ... chain private bool _suppressProperty = false; //Used to prevent a stack overflow due to a continuous UI -> Property -> UI -> ... chain private bool _isBinding = false; private object _boundObject; private Type _boundObjectType; private PropertyInfo _boundProperty; /// /// Binds the specified data source. /// /// The data source. /// Name of the property. public void Bind(object dataSource, string propertyName) { Check.NotNull(dataSource, "dataSource"); Check.NotEmpty(propertyName, "member"); try { _isBinding = true; if (_boundObject != null) { var i = _boundObject as INotifyPropertyChanged; if (i != null) i.PropertyChanged -= OnBoundObjectPropertyChanged; } _boundObject = dataSource; _boundObjectType = _boundObject.GetType(); _boundProperty = _boundObjectType.GetProperty(propertyName); if (_boundProperty == null) throw new InvalidOperationException("Could not find property " + _boundProperty + " of databound object (" + _boundObjectType.Name + ")"); //LOCALIZEME //Set initial value var val = _boundProperty.GetValue(_boundObject, null); if (val != null) this.Content = val.ToString(); else this.Content = null; var inp = _boundObject as INotifyPropertyChanged; if (inp != null) { inp.PropertyChanged += OnBoundObjectPropertyChanged; } } finally { _isBinding = false; } } void OnBoundObjectPropertyChanged(object sender, PropertyChangedEventArgs e) { if (_isBinding) return; if (_suppressUI) return; if (_boundProperty.Name != e.PropertyName) return; try { _suppressProperty = true; var val = _boundProperty.GetValue(_boundObject, null); if (val != null) this.Content = val.ToString(); else this.Content = null; } finally { _suppressProperty = false; } } } }