505 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			505 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Text;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Windows.Forms;
 | 
						|
using System.Globalization;
 | 
						|
using System.Drawing;
 | 
						|
using System.Security;
 | 
						|
using System.Reflection;
 | 
						|
using System.Collections;
 | 
						|
using System.ComponentModel.Design.Serialization;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// Defines class which described single binding.
 | 
						|
    /// </summary>
 | 
						|
    [TypeConverter(typeof(BindingDefConverer)), DesignTimeVisible(false), ToolboxItem(false)]
 | 
						|
    public class BindingDef : INotifyPropertyChanged
 | 
						|
    {
 | 
						|
        #region Dependency Properties & Events
 | 
						|
        public event DataConvertEventHandler Format;
 | 
						|
        /// <summary>
 | 
						|
        /// Raises Format event.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">Provides event arguments.</param>
 | 
						|
        protected virtual void OnFormat(DataConvertEventArgs e)
 | 
						|
        {
 | 
						|
            DataConvertEventHandler handler = Format;
 | 
						|
            if (handler != null)
 | 
						|
                handler(this, e);
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Constructor
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the BindingDef class.
 | 
						|
        /// </summary>
 | 
						|
        public BindingDef()
 | 
						|
        {
 | 
						|
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the BindingDef class.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="propertyName"></param>
 | 
						|
        /// <param name="dataMember"></param>
 | 
						|
        public BindingDef(string propertyName, string dataMember)
 | 
						|
        {
 | 
						|
            _PropertyName = propertyName;
 | 
						|
            _PropertyPath = propertyName.Split('.');
 | 
						|
            _DataMember = dataMember;
 | 
						|
            _BindingMemberInfo = new BindingMemberInfo(dataMember);
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Implementation
 | 
						|
        /// <summary>
 | 
						|
        /// Updates specified item PropertyName with the data from data object property specified by DataMember. 
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="item">Item to set PropertyName on.</param>
 | 
						|
        /// <param name="data">Data to retrieve DataMember value from.</param>
 | 
						|
        public void Update(object item, object data)
 | 
						|
        {
 | 
						|
            Update(null, item, data);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates specified item PropertyName with the data from data object property specified by DataMember. 
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="dataManager">CurrencyManager to use</param>
 | 
						|
        /// <param name="item">Item to set PropertyName on.</param>
 | 
						|
        /// <param name="data">Data to retrieve DataMember value from.</param>
 | 
						|
        public void Update(ItemVisualGenerator generator, object item, object data)
 | 
						|
        {
 | 
						|
            string propertyName = _PropertyName;
 | 
						|
 | 
						|
            if (item is BaseItem && _PropertyPath.Length > 1)
 | 
						|
            {
 | 
						|
                // Dig into child items
 | 
						|
                BaseItem parent = (BaseItem)item;
 | 
						|
                for (int i = 0; i < _PropertyPath.Length - 1; i++)
 | 
						|
                {
 | 
						|
                    parent = parent.SubItems[_PropertyPath[i]];
 | 
						|
                }
 | 
						|
                item = parent;
 | 
						|
                propertyName = _PropertyPath[_PropertyPath.Length - 1];
 | 
						|
            }
 | 
						|
            
 | 
						|
            PropertyInfo targetProp = item.GetType().GetProperty(propertyName);
 | 
						|
            if (targetProp.PropertyType == typeof(string))
 | 
						|
                targetProp.SetValue(item, GetDataText(generator, data, _DataMember), null);
 | 
						|
            else
 | 
						|
                targetProp.SetValue(item, GetDataValue(generator, data, _DataMember, GetPropertyValue(generator, data, _DataMember)), null);
 | 
						|
        }
 | 
						|
 | 
						|
        private static TypeConverter stringTypeConverter;
 | 
						|
        private string GetDataText(ItemVisualGenerator generator, object data, string fieldName)
 | 
						|
        {
 | 
						|
            object propertyValue = GetPropertyValue(generator, data, fieldName);
 | 
						|
            return GetDataText(generator, data, fieldName, propertyValue);
 | 
						|
        }
 | 
						|
        private string GetDataText(ItemVisualGenerator generator, object data, string fieldName, object propertyValue)
 | 
						|
        {
 | 
						|
            if (!_FormattingEnabled)
 | 
						|
            {
 | 
						|
                if (data == null)
 | 
						|
                {
 | 
						|
                    return string.Empty;
 | 
						|
                }
 | 
						|
                if (propertyValue == null)
 | 
						|
                {
 | 
						|
                    return "";
 | 
						|
                }
 | 
						|
                return Convert.ToString(propertyValue, CultureInfo.CurrentCulture);
 | 
						|
            }
 | 
						|
 | 
						|
            DataConvertEventArgs e = new DataConvertEventArgs(propertyValue, typeof(string), data, fieldName);
 | 
						|
            this.OnFormat(e);
 | 
						|
            if ((e.Value != data) && (e.Value is string))
 | 
						|
            {
 | 
						|
                return (string)e.Value;
 | 
						|
            }
 | 
						|
            if (stringTypeConverter == null)
 | 
						|
            {
 | 
						|
                stringTypeConverter = TypeDescriptor.GetConverter(typeof(string));
 | 
						|
            }
 | 
						|
            try
 | 
						|
            {
 | 
						|
                return (string)FormatHelper.FormatObject(propertyValue, typeof(string), generator.GetFieldConverter(fieldName), stringTypeConverter, _FormatString, _FormatInfo, null, DBNull.Value);
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                if (ex is SecurityException || IsCriticalException(ex))
 | 
						|
                {
 | 
						|
                    throw;
 | 
						|
                }
 | 
						|
                return ((propertyValue != null) ? Convert.ToString(data, CultureInfo.CurrentCulture) : "");
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private object GetDataValue(ItemVisualGenerator generator, object data, string fieldName, object propertyValue)
 | 
						|
        {
 | 
						|
            if (!_FormattingEnabled)
 | 
						|
            {
 | 
						|
                return propertyValue;
 | 
						|
            }
 | 
						|
 | 
						|
            DataConvertEventArgs e = new DataConvertEventArgs(propertyValue, typeof(object), data, fieldName);
 | 
						|
            this.OnFormat(e);
 | 
						|
            return e.Value;
 | 
						|
        }
 | 
						|
 | 
						|
        private static bool IsCriticalException(Exception ex)
 | 
						|
        {
 | 
						|
            return (((((ex is NullReferenceException) || (ex is StackOverflowException)) || ((ex is OutOfMemoryException) || (ex is System.Threading.ThreadAbortException))) || ((ex is ExecutionEngineException) || (ex is IndexOutOfRangeException))) || (ex is AccessViolationException));
 | 
						|
        }
 | 
						|
 | 
						|
        private object GetPropertyValue(ItemVisualGenerator generator, object data, string fieldName)
 | 
						|
        {
 | 
						|
            if ((data != null) && (fieldName.Length > 0))
 | 
						|
            {
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    PropertyDescriptor descriptor = null;
 | 
						|
                    if (generator.DataManager != null)
 | 
						|
                    {
 | 
						|
                        descriptor = generator.DataManager.GetItemProperties().Find(fieldName, true);
 | 
						|
                    }
 | 
						|
                    if(descriptor == null)
 | 
						|
                    {
 | 
						|
                        descriptor = TypeDescriptor.GetProperties(data).Find(fieldName, true);
 | 
						|
                    }
 | 
						|
                    if (descriptor != null)
 | 
						|
                    {
 | 
						|
                        data = descriptor.GetValue(data);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                catch
 | 
						|
                {
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (data == DBNull.Value && _NullValue != null)
 | 
						|
                return _NullValue;
 | 
						|
 | 
						|
            return data;
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Properties
 | 
						|
        private string[] _PropertyPath = new string[0];
 | 
						|
        private string _PropertyName = "";
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the property name binding is attached to.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(""), Category("Data"), Description("Indicates property name binding is attached to.")]
 | 
						|
        public string PropertyName
 | 
						|
        {
 | 
						|
            get { return _PropertyName; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _PropertyName)
 | 
						|
                {
 | 
						|
                    string oldValue = _PropertyName;
 | 
						|
                    _PropertyName = value;
 | 
						|
                    OnPropertyNameChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when PropertyName property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnPropertyNameChanged(string oldValue, string newValue)
 | 
						|
        {
 | 
						|
            _PropertyPath = newValue.Split('.');
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("PropertyName"));
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the reference to BindingMemberInfo created based on DataMember.
 | 
						|
        /// </summary>
 | 
						|
        [Browsable(false)]
 | 
						|
        public BindingMemberInfo BindingMemberInfo
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return _BindingMemberInfo;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private BindingMemberInfo _BindingMemberInfo;
 | 
						|
        private string _DataMember = "";
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the data member name which holds data that PropertyName is populated with.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(""), Category("Data"), Description("Indicates data member name which holds data that PropertyName is populated with.")]
 | 
						|
        public string DataMember
 | 
						|
        {
 | 
						|
            get { return _DataMember; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value == null) value = "";
 | 
						|
                if (value != _DataMember)
 | 
						|
                {
 | 
						|
                    string oldValue = _DataMember;
 | 
						|
                    _DataMember = value;
 | 
						|
                    OnDataMemberChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when DataMember property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnDataMemberChanged(string oldValue, string newValue)
 | 
						|
        {
 | 
						|
            if (!string.IsNullOrEmpty(newValue))
 | 
						|
                _BindingMemberInfo = new BindingMemberInfo(newValue);
 | 
						|
            else
 | 
						|
                _BindingMemberInfo = new BindingMemberInfo();
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("DataMember"));
 | 
						|
        }
 | 
						|
 | 
						|
        private bool _FormattingEnabled = false;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether type conversion and formatting is applied to the property data.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(false), Category("Data"), Description("Indicates whether type conversion and formatting is applied to the property data.")]
 | 
						|
        public bool FormattingEnabled
 | 
						|
        {
 | 
						|
            get { return _FormattingEnabled; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _FormattingEnabled)
 | 
						|
                {
 | 
						|
                    bool oldValue = _FormattingEnabled;
 | 
						|
                    _FormattingEnabled = value;
 | 
						|
                    OnFormattingEnabledChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when FormattingEnabled property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnFormattingEnabledChanged(bool oldValue, bool newValue)
 | 
						|
        {
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("FormattingEnabled"));
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        private string _FormatString = "";
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets format specifier characters that indicate how a value is to be displayed.
 | 
						|
        /// For more information, see Formatting Overview: http://msdn.microsoft.com/en-us/library/26etazsy%28v=vs.71%29.aspx 
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(""), Category("Data"), Description("Indicates format specifier characters that indicate how a value is to be displayed.")]
 | 
						|
        public string FormatString
 | 
						|
        {
 | 
						|
            get { return _FormatString; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _FormatString)
 | 
						|
                {
 | 
						|
                    string oldValue = _FormatString;
 | 
						|
                    _FormatString = value;
 | 
						|
                    OnFormatStringChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when FormatString property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnFormatStringChanged(string oldValue, string newValue)
 | 
						|
        {
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("FormatString"));
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        private IFormatProvider _FormatInfo = null;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the IFormatProvider that provides custom formatting behavior. 
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(null), Category("Data"), Description("Indicates IFormatProvider that provides custom formatting behavior.")]
 | 
						|
        public IFormatProvider FormatInfo
 | 
						|
        {
 | 
						|
            get { return _FormatInfo; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _FormatInfo)
 | 
						|
                {
 | 
						|
                    IFormatProvider oldValue = _FormatInfo;
 | 
						|
                    _FormatInfo = value;
 | 
						|
                    OnFormatInfoChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when FormatInfo property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnFormatInfoChanged(IFormatProvider oldValue, IFormatProvider newValue)
 | 
						|
        {
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("FormatInfo"));
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        private object _NullValue = null;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the Object to be set as the target property when the data source contains a DBNull value. 
 | 
						|
        /// The data source must contain DBNull for the NullValue property to be correctly applied. 
 | 
						|
        /// If the data source type is a type such as a string or integer the value of the NullValue property will be ignored. 
 | 
						|
        /// Also, the NullValue property is ignored if it is set to null. 
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(null), Category("Data"), Description("Indicates Object to be set as the control property when the data source contains a DBNull value. ")]
 | 
						|
        [System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter))]
 | 
						|
        public object NullValue
 | 
						|
        {
 | 
						|
            get { return _NullValue; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (value != _NullValue)
 | 
						|
                {
 | 
						|
                    object oldValue = _NullValue;
 | 
						|
                    _NullValue = value;
 | 
						|
                    OnNullValueChanged(oldValue, value);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Called when NullValue property has changed.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="oldValue">Old property value</param>
 | 
						|
        /// <param name="newValue">New property value</param>
 | 
						|
        protected virtual void OnNullValueChanged(object oldValue, object newValue)
 | 
						|
        {
 | 
						|
            OnPropertyChanged(new PropertyChangedEventArgs("NullValue"));
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region INotifyPropertyChanged Members
 | 
						|
        /// <summary>
 | 
						|
        /// Raises the PropertyChanged event.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">Provides event arguments.</param>
 | 
						|
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
 | 
						|
        {
 | 
						|
            PropertyChangedEventHandler handler = PropertyChanged;
 | 
						|
            if (handler != null) handler(this, e);
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Occurs when property on BindingDef object has changed.
 | 
						|
        /// </summary>
 | 
						|
        [Description("Occurs when property on BindingDef object has changed.Occurs when property on BindingDef object has changed.")]
 | 
						|
        public event PropertyChangedEventHandler PropertyChanged;
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Represents the method that will handle converting for bindings.
 | 
						|
    /// </summary>
 | 
						|
    /// <param name="sender"></param>
 | 
						|
    /// <param name="e"></param>
 | 
						|
    public delegate void DataConvertEventHandler(object sender, DataConvertEventArgs e);
 | 
						|
    public class DataConvertEventArgs : ConvertEventArgs
 | 
						|
    {
 | 
						|
        // Fields
 | 
						|
        private object _DataItem;
 | 
						|
 | 
						|
        // Methods
 | 
						|
        public DataConvertEventArgs(object value, Type desiredType, object dataItem, string fieldName)
 | 
						|
            : base(value, desiredType)
 | 
						|
        {
 | 
						|
            _DataItem = dataItem;
 | 
						|
            _FieldName = fieldName;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the reference to the item being converted.
 | 
						|
        /// </summary>
 | 
						|
        public object DataItem
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return _DataItem;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private string _FieldName = "";
 | 
						|
        /// <summary>
 | 
						|
        /// Get the reference to the name of the field or property on the item that needs conversion.
 | 
						|
        /// </summary>
 | 
						|
        public string FieldName
 | 
						|
        {
 | 
						|
            get { return _FieldName; }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Represents BindingDefConverer converter.
 | 
						|
    /// </summary>
 | 
						|
    public class BindingDefConverer : TypeConverter
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Creates new instance of the class.
 | 
						|
        /// </summary>
 | 
						|
        public BindingDefConverer() { }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Checks whether conversion can be made to specified type.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="context">Context Information.</param>
 | 
						|
        /// <param name="destinationType">Destination type.</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
 | 
						|
        {
 | 
						|
            if (destinationType == typeof(InstanceDescriptor))
 | 
						|
                return true;
 | 
						|
            return base.CanConvertTo(context, destinationType);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Converts object to specified type.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="context">Context information.</param>
 | 
						|
        /// <param name="culture">Culture information.</param>
 | 
						|
        /// <param name="value">Object to convert.</param>
 | 
						|
        /// <param name="destinationType">Destination type.</param>
 | 
						|
        /// <returns>Object converted to destination type.</returns>
 | 
						|
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
 | 
						|
        {
 | 
						|
            if (destinationType == null)
 | 
						|
                throw new ArgumentNullException("destinationType");
 | 
						|
 | 
						|
            if ((destinationType == typeof(InstanceDescriptor)) && (value is BindingDef))
 | 
						|
            {
 | 
						|
                BindingDef info = (BindingDef)value;
 | 
						|
                Type[] constructorParams = null;
 | 
						|
                MemberInfo constructorMemberInfo = null;
 | 
						|
                object[] constructorValues = null;
 | 
						|
 | 
						|
                constructorParams = new Type[] { typeof(string), typeof(string) };
 | 
						|
                constructorMemberInfo = typeof(BindingDef).GetConstructor(constructorParams);
 | 
						|
                constructorValues = new object[] { info.PropertyName, info.DataMember };
 | 
						|
 | 
						|
                if (constructorMemberInfo != null)
 | 
						|
                {
 | 
						|
                    return new InstanceDescriptor(constructorMemberInfo, constructorValues);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return base.ConvertTo(context, culture, value, destinationType);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |