External/Aga.Controls/Tree/NodeControls/BindableControl.cs
author sl
Thu, 01 Jan 2015 23:35:49 +0100
changeset 405 5715aefd2bcc
permissions -rw-r--r--
SharpDisplay: Migrating to new robust client scheme.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Reflection;
     5 using System.ComponentModel;
     6 
     7 namespace Aga.Controls.Tree.NodeControls
     8 {
     9 	public abstract class BindableControl : NodeControl
    10 	{
    11 		private struct MemberAdapter
    12 		{
    13 			private object _obj;
    14 			private PropertyInfo _pi;
    15 			private FieldInfo _fi;
    16 
    17 			public static readonly MemberAdapter Empty = new MemberAdapter();
    18 
    19 			public Type MemberType
    20 			{
    21 				get
    22 				{
    23 					if (_pi != null)
    24 						return _pi.PropertyType;
    25 					else if (_fi != null)
    26 						return _fi.FieldType;
    27 					else
    28 						return null;
    29 				}
    30 			}
    31 
    32 			public object Value
    33 			{
    34 				get
    35 				{
    36 					if (_pi != null && _pi.CanRead)
    37 						return _pi.GetValue(_obj, null);
    38 					else if (_fi != null)
    39 						return _fi.GetValue(_obj);
    40 					else
    41 						return null;
    42 				}
    43 				set
    44 				{
    45 					if (_pi != null && _pi.CanWrite)
    46 						_pi.SetValue(_obj, value, null);
    47 					else if (_fi != null)
    48 						_fi.SetValue(_obj, value);
    49 				}
    50 			}
    51 
    52 			public MemberAdapter(object obj, PropertyInfo pi)
    53 			{
    54 				_obj = obj;
    55 				_pi = pi;
    56 				_fi = null;
    57 			}
    58 
    59 			public MemberAdapter(object obj, FieldInfo fi)
    60 			{
    61 				_obj = obj;
    62 				_fi = fi;
    63 				_pi = null;
    64 			}
    65 		}
    66 
    67 		#region Properties
    68 
    69 		private bool _virtualMode = false;
    70 		[DefaultValue(false), Category("Data")]
    71 		public bool VirtualMode
    72 		{
    73 			get { return _virtualMode; }
    74 			set { _virtualMode = value; }
    75 		}
    76 
    77 		private string _propertyName = "";
    78 		[DefaultValue(""), Category("Data")]
    79 		public string DataPropertyName
    80 		{
    81 			get { return _propertyName; }
    82 			set 
    83 			{
    84 				if (_propertyName == null)
    85 					_propertyName = string.Empty;
    86 				_propertyName = value; 
    87 			}
    88 		}
    89 
    90 		private bool _incrementalSearchEnabled = false;
    91 		[DefaultValue(false)]
    92 		public bool IncrementalSearchEnabled
    93 		{
    94 			get { return _incrementalSearchEnabled; }
    95 			set { _incrementalSearchEnabled = value; }
    96 		}
    97 
    98 		#endregion
    99 
   100 		public virtual object GetValue(TreeNodeAdv node)
   101 		{
   102 			if (VirtualMode)
   103 			{
   104 				NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
   105 				OnValueNeeded(args);
   106 				return args.Value;
   107 			}
   108 			else
   109 			{
   110 				try
   111 				{
   112 					return GetMemberAdapter(node).Value;
   113 				}
   114 				catch (TargetInvocationException ex)
   115 				{
   116 					if (ex.InnerException != null)
   117 						throw new ArgumentException(ex.InnerException.Message, ex.InnerException);
   118 					else
   119 						throw new ArgumentException(ex.Message);
   120 				}
   121 			}
   122 		}
   123 
   124 		public virtual void SetValue(TreeNodeAdv node, object value)
   125 		{
   126 			if (VirtualMode)
   127 			{
   128 				NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
   129 				args.Value = value;
   130 				OnValuePushed(args);
   131 			}
   132 			else
   133 			{
   134 				try
   135 				{
   136 					MemberAdapter ma = GetMemberAdapter(node);
   137 					ma.Value = value;
   138 				}
   139 				catch (TargetInvocationException ex)
   140 				{
   141 					if (ex.InnerException != null)
   142 						throw new ArgumentException(ex.InnerException.Message, ex.InnerException);
   143 					else
   144 						throw new ArgumentException(ex.Message);
   145 				}
   146 			}
   147 		}
   148 
   149 		public Type GetPropertyType(TreeNodeAdv node)
   150 		{
   151 			return GetMemberAdapter(node).MemberType;
   152 		}
   153 
   154 		private MemberAdapter GetMemberAdapter(TreeNodeAdv node)
   155 		{
   156 			if (node.Tag != null && !string.IsNullOrEmpty(DataPropertyName))
   157 			{
   158 				Type type = node.Tag.GetType();
   159 				PropertyInfo pi = type.GetProperty(DataPropertyName);
   160 				if (pi != null)
   161 					return new MemberAdapter(node.Tag, pi);
   162 				else
   163 				{
   164 					FieldInfo fi = type.GetField(DataPropertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
   165 					if (fi != null)
   166 						return new MemberAdapter(node.Tag, fi);
   167 				}
   168 			}
   169 			return MemberAdapter.Empty;
   170 		}
   171 
   172 		public override string ToString()
   173 		{
   174 			if (string.IsNullOrEmpty(DataPropertyName))
   175 				return GetType().Name;
   176 			else
   177 				return string.Format("{0} ({1})", GetType().Name, DataPropertyName);
   178 		}
   179 
   180 		public event EventHandler<NodeControlValueEventArgs> ValueNeeded;
   181 		private void OnValueNeeded(NodeControlValueEventArgs args)
   182 		{
   183 			if (ValueNeeded != null)
   184 				ValueNeeded(this, args);
   185 		}
   186 
   187 		public event EventHandler<NodeControlValueEventArgs> ValuePushed;
   188 		private void OnValuePushed(NodeControlValueEventArgs args)
   189 		{
   190 			if (ValuePushed != null)
   191 				ValuePushed(this, args);
   192 		}
   193 	}
   194 }