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);
 | |
|         }
 | |
|     }
 | |
| }
 |