namespace PropertyGridEx
{
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Data;
using System.Xml.Serialization;
[Serializable(), XmlRootAttribute("CustomProperty")]
public class CustomProperty
{
#region "Private variables"
// Common properties
protected string sName = "";
protected object oValue = null;
protected bool bIsReadOnly = false;
protected bool bVisible = true;
protected string sDescription = "";
protected string sCategory = "";
protected bool bIsPassword = false;
protected bool bIsPercentage = false;
protected bool bParenthesize = false;
// Filename editor properties
protected string sFilter = null;
protected UIFilenameEditor.FileDialogType eDialogType = UIFilenameEditor.FileDialogType.LoadFileDialog;
protected bool bUseFileNameEditor = false;
// Custom choices properties
protected CustomChoices oChoices = null;
// Browsable properties
protected bool bIsBrowsable = false;
protected BrowsableTypeConverter.LabelStyle eBrowsablePropertyLabel = BrowsableTypeConverter.LabelStyle.lsEllipsis;
// Dynamic properties
protected bool bRef = false;
protected object oRef = null;
protected string sProp = "";
// Databinding properties
protected object oDatasource = null;
protected string sDisplayMember = null;
protected string sValueMember = null;
protected object oSelectedValue = null;
protected object oSelectedItem = null;
protected bool bIsDropdownResizable = false;
// 3-dots button event handler
protected UICustomEventEditor.OnClick MethodDelegate;
// Extended Attributes
[NonSerialized()]protected AttributeCollection oCustomAttributes = null;
protected object oTag = null;
protected object oDefaultValue = null;
protected Type oDefaultType = null;
// Custom Editor and Custom Type Converter
[NonSerialized()]protected UITypeEditor oCustomEditor = null;
[NonSerialized()]protected TypeConverter oCustomTypeConverter = null;
#endregion
#region "Public methods"
public CustomProperty()
{
sName = "New Property";
oValue = new string(' ',0);
}
public CustomProperty(string strName, object objValue, bool boolIsReadOnly, string strCategory, string strDescription, bool boolVisible)
{
sName = strName;
oValue = objValue;
bIsReadOnly = boolIsReadOnly;
sDescription = strDescription;
sCategory = strCategory;
bVisible = boolVisible;
if (oValue != null)
{
oDefaultValue = oValue;
}
}
public CustomProperty(string strName, ref object objRef, string strProp, bool boolIsReadOnly, string strCategory, string strDescription, bool boolVisible)
{
sName = strName;
bIsReadOnly = boolIsReadOnly;
sDescription = strDescription;
sCategory = strCategory;
bVisible = boolVisible;
bRef = true;
oRef = objRef;
sProp = strProp;
if (Value != null)
{
oDefaultValue = Value;
}
}
public void RebuildAttributes()
{
if (bUseFileNameEditor)
{
BuildAttributes_FilenameEditor();
}
else if (oChoices != null)
{
BuildAttributes_CustomChoices();
}
else if (oDatasource != null)
{
BuildAttributes_ListboxEditor();
}
else if (bIsBrowsable)
{
BuildAttributes_BrowsableProperty();
}
}
#endregion
#region "Private methods"
private void BuildAttributes_FilenameEditor()
{
ArrayList attrs = new ArrayList();
UIFilenameEditor.FileDialogFilterAttribute FilterAttribute = new UIFilenameEditor.FileDialogFilterAttribute(sFilter);
UIFilenameEditor.SaveFileAttribute SaveDialogAttribute = new UIFilenameEditor.SaveFileAttribute();
Attribute[] attrArray;
attrs.Add(FilterAttribute);
if (eDialogType == UIFilenameEditor.FileDialogType.SaveFileDialog)
{
attrs.Add(SaveDialogAttribute);
}
attrArray = (System.Attribute[]) attrs.ToArray(typeof(Attribute));
oCustomAttributes = new AttributeCollection(attrArray);
}
private void BuildAttributes_CustomChoices()
{
if (oChoices != null)
{
CustomChoices.CustomChoicesAttributeList list = new CustomChoices.CustomChoicesAttributeList(oChoices.Items);
ArrayList attrs = new ArrayList();
Attribute[] attrArray;
attrs.Add(list);
attrArray = (System.Attribute[]) attrs.ToArray(typeof(Attribute));
oCustomAttributes = new AttributeCollection(attrArray);
}
}
private void BuildAttributes_ListboxEditor()
{
if (oDatasource != null)
{
UIListboxEditor.UIListboxDatasource ds = new UIListboxEditor.UIListboxDatasource(ref oDatasource);
UIListboxEditor.UIListboxValueMember vm = new UIListboxEditor.UIListboxValueMember(sValueMember);
UIListboxEditor.UIListboxDisplayMember dm = new UIListboxEditor.UIListboxDisplayMember(sDisplayMember);
UIListboxEditor.UIListboxIsDropDownResizable ddr = null;
ArrayList attrs = new ArrayList();
attrs.Add(ds);
attrs.Add(vm);
attrs.Add(dm);
if (bIsDropdownResizable)
{
ddr = new UIListboxEditor.UIListboxIsDropDownResizable();
attrs.Add(ddr);
}
Attribute[] attrArray;
attrArray = (System.Attribute[]) attrs.ToArray(typeof(Attribute));
oCustomAttributes = new AttributeCollection(attrArray);
}
}
private void BuildAttributes_BrowsableProperty()
{
BrowsableTypeConverter.BrowsableLabelStyleAttribute style = new BrowsableTypeConverter.BrowsableLabelStyleAttribute(eBrowsablePropertyLabel);
oCustomAttributes = new AttributeCollection(new Attribute[] { style });
}
private void BuildAttributes_CustomEventProperty()
{
UICustomEventEditor.DelegateAttribute attr = new UICustomEventEditor.DelegateAttribute(MethodDelegate);
oCustomAttributes = new AttributeCollection(new Attribute[] {attr});
}
private object DataColumn
{
get
{
DataRow oRow = (System.Data.DataRow) oRef;
if (oRow.RowState != DataRowState.Deleted)
{
if (oDatasource == null)
{
return oRow[sProp];
}
else
{
DataTable oLookupTable = oDatasource as DataTable;
if (oLookupTable != null)
{
return oLookupTable.Select(sValueMember + "=" + oRow[sProp])[0][sDisplayMember];
}
else
{
Information.Err().Raise(Constants.vbObjectError + 513, null, "Bind of DataRow with a DataSource that is not a DataTable is not possible", null, null);
return null;
}
}
}
else
{
return null;
}
}
set
{
DataRow oRow = (System.Data.DataRow) oRef;
if (oRow.RowState != DataRowState.Deleted)
{
if (oDatasource == null)
{
oRow[sProp] = value;
}
else
{
DataTable oLookupTable = oDatasource as DataTable;
if (oLookupTable != null)
{
if (oLookupTable.Columns[sDisplayMember].DataType.Equals(System.Type.GetType("System.String")))
{
oRow[sProp] = oLookupTable.Select(oLookupTable.Columns[sDisplayMember].ColumnName + " = \'" + value + "\'")[0][sValueMember];
}
else
{
oRow[sProp] = oLookupTable.Select(oLookupTable.Columns[sDisplayMember].ColumnName + " = " + value)[0][sValueMember];
}
}
else
{
Information.Err().Raise(Constants.vbObjectError + 514, null, "Bind of DataRow with a DataSource that is not a DataTable is impossible", null, null);
}
}
}
}
}
#endregion
#region "Public properties"
[Category("Appearance"), DisplayName("Name"), DescriptionAttribute("Display Name of the CustomProperty."), ParenthesizePropertyName(true), XmlElementAttribute("Name")]public string Name
{
get
{
return sName;
}
set
{
sName = value;
}
}
[Category("Appearance"), DisplayName("ReadOnly"), DescriptionAttribute("Set read only attribute of the CustomProperty."), XmlElementAttribute("ReadOnly")]public bool IsReadOnly
{
get
{
return bIsReadOnly;
}
set
{
bIsReadOnly = value;
}
}
[Category("Appearance"), DescriptionAttribute("Set visibility attribute of the CustomProperty.")]public bool Visible
{
get
{
return bVisible;
}
set
{
bVisible = value;
}
}
[Category("Appearance"), DescriptionAttribute("Represent the Value of the CustomProperty.")]public object Value
{
get
{
if (bRef)
{
if (oRef.GetType() == typeof(DataRow) || oRef.GetType().IsSubclassOf(typeof(DataRow)))
return this.DataColumn;
else
return Interaction.CallByName(oRef, sProp, CallType.Get, null);
}
else
{
return oValue;
}
}
set
{
if (bRef)
{
if (oRef.GetType() == typeof(DataRow) || oRef.GetType().IsSubclassOf(typeof(DataRow)))
this.DataColumn = value;
else
Interaction.CallByName(oRef, sProp, CallType.Set, value);
}
else
{
oValue = value;
}
}
}
[Category("Appearance"), DescriptionAttribute("Set description associated with the CustomProperty.")]public string Description
{
get
{
return sDescription;
}
set
{
sDescription = value;
}
}
[Category("Appearance"), DescriptionAttribute("Set category associated with the CustomProperty.")]public string Category
{
get
{
return sCategory;
}
set
{
sCategory = value;
}
}
[XmlIgnore()]public System.Type Type
{
get
{
if (Value != null)
{
return Value.GetType();
}
else
{
if (oDefaultValue != null)
{
return oDefaultValue.GetType();
}
else
{
return oDefaultType;
}
}
}
}
[XmlIgnore()]public AttributeCollection Attributes
{
get
{
return oCustomAttributes;
}
set
{
oCustomAttributes = value;
}
}
[Category("Behavior"), DescriptionAttribute("Indicates if the property is browsable or not."), XmlElementAttribute(IsNullable = false)]public bool IsBrowsable
{
get
{
return bIsBrowsable;
}
set
{
bIsBrowsable = value;
if (value == true)
{
BuildAttributes_BrowsableProperty();
}
}
}
[Category("Appearance"), DisplayName("Parenthesize"), DescriptionAttribute("Indicates whether the name of the associated property is displayed with parentheses in the Properties window."), DefaultValue(false), XmlElementAttribute("Parenthesize")]public bool Parenthesize
{
get
{
return bParenthesize;
}
set
{
bParenthesize = value;
}
}
[Category("Behavior"), DescriptionAttribute("Indicates the style of the label when a property is browsable."), XmlElementAttribute(IsNullable = false)]public BrowsableTypeConverter.LabelStyle BrowsableLabelStyle
{
get
{
return eBrowsablePropertyLabel;
}
set
{
bool Update = false;
if (value != eBrowsablePropertyLabel)
{
Update = true;
}
eBrowsablePropertyLabel = value;
if (Update)
{
BrowsableTypeConverter.BrowsableLabelStyleAttribute style = new BrowsableTypeConverter.BrowsableLabelStyleAttribute(value);
oCustomAttributes = new AttributeCollection(new Attribute[] {style});
}
}
}
[Category("Behavior"), DescriptionAttribute("Indicates if the property is masked or not."), XmlElementAttribute(IsNullable = false)]public bool IsPassword
{
get
{
return bIsPassword;
}
set
{
bIsPassword = value;
}
}
[Category("Behavior"), DescriptionAttribute("Indicates if the property represents a value in percentage."), XmlElementAttribute(IsNullable = false)]public bool IsPercentage
{
get
{
return bIsPercentage;
}
set
{
bIsPercentage = value;
}
}
[Category("Behavior"), DescriptionAttribute("Indicates if the property uses a FileNameEditor converter."), XmlElementAttribute(IsNullable = false)]public bool UseFileNameEditor
{
get
{
return bUseFileNameEditor;
}
set
{
bUseFileNameEditor = value;
}
}
[Category("Behavior"), DescriptionAttribute("Apply a filter to FileNameEditor converter."), XmlElementAttribute(IsNullable = false)]public string FileNameFilter
{
get
{
return sFilter;
}
set
{
bool UpdateAttributes = false;
if (value != sFilter)
{
UpdateAttributes = true;
}
sFilter = value;
if (UpdateAttributes)
{
BuildAttributes_FilenameEditor();
}
}
}
[Category("Behavior"), DescriptionAttribute("DialogType of the FileNameEditor."), XmlElementAttribute(IsNullable = false)]public UIFilenameEditor.FileDialogType FileNameDialogType
{
get
{
return eDialogType;
}
set
{
bool UpdateAttributes = false;
if (value != eDialogType)
{
UpdateAttributes = true;
}
eDialogType = value;
if (UpdateAttributes)
{
BuildAttributes_FilenameEditor();
}
}
}
[Category("Behavior"), DescriptionAttribute("Custom Choices list."), XmlIgnore()]public CustomChoices Choices
{
get
{
return oChoices;
}
set
{
oChoices = value;
BuildAttributes_CustomChoices();
}
}
[Category("Databinding"), XmlIgnore()]public object Datasource
{
get
{
return oDatasource;
}
set
{
oDatasource = value;
BuildAttributes_ListboxEditor();
}
}
[Category("Databinding"), XmlElementAttribute(IsNullable = false)]
public string ValueMember
{
get
{
return sValueMember;
}
set
{
sValueMember = value;
BuildAttributes_ListboxEditor();
}
}
[Category("Databinding"), XmlElementAttribute(IsNullable = false)]
public string DisplayMember
{
get
{
return sDisplayMember;
}
set
{
sDisplayMember = value;
BuildAttributes_ListboxEditor();
}
}
[Category("Databinding"), XmlElementAttribute(IsNullable = false)]
public object SelectedValue
{
get
{
return oSelectedValue;
}
set
{
oSelectedValue = value;
}
}
[Category("Databinding"), XmlElementAttribute(IsNullable = false)]
public object SelectedItem
{
get
{
return oSelectedItem;
}
set
{
oSelectedItem = value;
}
}
[Category("Databinding"), XmlElementAttribute(IsNullable = false)]
public bool IsDropdownResizable
{
get
{
return bIsDropdownResizable;
}
set
{
bIsDropdownResizable = value;
BuildAttributes_ListboxEditor();
}
}
[XmlIgnore()]public UITypeEditor CustomEditor
{
get
{
return oCustomEditor;
}
set
{
oCustomEditor = value;
}
}
[XmlIgnore()]public TypeConverter CustomTypeConverter
{
get
{
return oCustomTypeConverter;
}
set
{
oCustomTypeConverter = value;
}
}
[XmlIgnore()]public object Tag
{
get
{
return oTag;
}
set
{
oTag = value;
}
}
[XmlIgnore()]public object DefaultValue
{
get
{
return oDefaultValue;
}
set
{
oDefaultValue = value;
}
}
[XmlIgnore()]public Type DefaultType
{
get
{
return oDefaultType;
}
set
{
oDefaultType = value;
}
}
[XmlIgnore()]public UICustomEventEditor.OnClick OnClick
{
get
{
return MethodDelegate;
}
set
{
MethodDelegate = value;
BuildAttributes_CustomEventProperty();
}
}
#endregion
#region "CustomPropertyDescriptor"
public class CustomPropertyDescriptor : PropertyDescriptor
{
protected CustomProperty oCustomProperty;
public CustomPropertyDescriptor(CustomProperty myProperty, Attribute[] attrs) : base(myProperty.Name, attrs)
{
if (myProperty == null)
{
oCustomProperty = null;
}
else
{
oCustomProperty = myProperty;
}
}
public override bool CanResetValue(object component)
{
if ((oCustomProperty.DefaultValue != null)|| (oCustomProperty.DefaultType != null))
{
return true;
}
else
{
return false;
}
}
public override System.Type ComponentType
{
get
{
return this.GetType();
}
}
public override object GetValue(object component)
{
return oCustomProperty.Value;
}
public override bool IsReadOnly
{
get
{
return oCustomProperty.IsReadOnly;
}
}
public override System.Type PropertyType
{
get
{
return oCustomProperty.Type;
}
}
public override void ResetValue(object component)
{
oCustomProperty.Value = oCustomProperty.DefaultValue;
this.OnValueChanged(component, EventArgs.Empty);
}
public override void SetValue(object component, object value)
{
oCustomProperty.Value = value;
this.OnValueChanged(component, EventArgs.Empty);
}
public override bool ShouldSerializeValue(object component)
{
object oValue = oCustomProperty.Value;
if ((oCustomProperty.DefaultValue != null)&& (oValue != null))
{
return ! oValue.Equals(oCustomProperty.DefaultValue);
}
else
{
return false;
}
}
public override string Description
{
get
{
return oCustomProperty.Description;
}
}
public override string Category
{
get
{
return oCustomProperty.Category;
}
}
public override string DisplayName
{
get
{
return oCustomProperty.Name;
}
}
public override bool IsBrowsable
{
get
{
return oCustomProperty.IsBrowsable;
}
}
public object CustomProperty
{
get
{
return oCustomProperty;
}
}
}
#endregion
}
}