Advertisement
Guest User

Untitled

a guest
Feb 6th, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.02 KB | None | 0 0
  1. // THIS SOFTWARE COMES "AS IS", WITH NO WARRANTIES. THIS
  2. // MEANS NO EXPRESS, IMPLIED OR STATUTORY WARRANTY, INCLUDING
  3. // WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY OR FITNESS
  4. // FOR A PARTICULAR PURPOSE OR ANY WARRANTY OF TITLE OR
  5. // NON-INFRINGEMENT.
  6. //
  7. // MICROSOFT WILL NOT BE LIABLE FOR ANY DAMAGES RELATED TO
  8. // THE SOFTWARE, INCLUDING DIRECT, INDIRECT, SPECIAL,
  9. // CONSEQUENTIAL OR INCIDENTAL DAMAGES, TO THE MAXIMUM EXTENT
  10. // THE LAW PERMITS, NO MATTER WHAT LEGAL THEORY IT IS
  11. // BASED ON.
  12. using System;
  13. using System.Windows.Input;
  14. using System.Collections.Generic;
  15. using System.ComponentModel;
  16.  
  17. namespace PersistingWorkflows
  18. {
  19. /// <summary>
  20. /// A map that exposes commands in a WPF binding friendly manner
  21. /// </summary>
  22. [TypeDescriptionProvider(typeof(CommandMapDescriptionProvider))]
  23. public class CommandMap
  24. {
  25. /// <summary>
  26. /// Add a named command to the command map
  27. /// </summary>
  28. /// <param name="commandName">The name of the command</param>
  29. /// <param name="executeMethod">The method to execute</param>
  30. public void AddCommand(string commandName, Action<object> executeMethod)
  31. {
  32. Commands[commandName] = new DelegateCommand(executeMethod);
  33. }
  34.  
  35. /// <summary>
  36. /// Add a named command to the command map
  37. /// </summary>
  38. /// <param name="commandName">The name of the command</param>
  39. /// <param name="executeMethod">The method to execute</param>
  40. /// <param name="canExecuteMethod">The method to execute to check if the command can be executed</param>
  41. public void AddCommand(string commandName, Action<object> executeMethod, Predicate<object> canExecuteMethod)
  42. {
  43. Commands[commandName] = new DelegateCommand(executeMethod, canExecuteMethod);
  44. }
  45.  
  46. /// <summary>
  47. /// Remove a command from the command map
  48. /// </summary>
  49. /// <param name="commandName">The name of the command</param>
  50. public void RemoveCommand(string commandName)
  51. {
  52. Commands.Remove(commandName);
  53. }
  54.  
  55. /// <summary>
  56. /// Expose the dictionary of commands
  57. /// </summary>
  58. protected Dictionary<string, ICommand> Commands
  59. {
  60. get
  61. {
  62. if (null == _commands)
  63. _commands = new Dictionary<string, ICommand>();
  64.  
  65. return _commands;
  66. }
  67. }
  68.  
  69. /// <summary>
  70. /// Store the commands
  71. /// </summary>
  72. private Dictionary<string, ICommand> _commands;
  73.  
  74. /// <summary>
  75. /// Implements ICommand in a delegate friendly way
  76. /// </summary>
  77. private class DelegateCommand : ICommand
  78. {
  79. /// <summary>
  80. /// Create a command that can always be executed
  81. /// </summary>
  82. /// <param name="executeMethod">The method to execute when the command is called</param>
  83. public DelegateCommand(Action<object> executeMethod) : this(executeMethod, null) { }
  84.  
  85. /// <summary>
  86. /// Create a delegate command which executes the canExecuteMethod before executing the executeMethod
  87. /// </summary>
  88. /// <param name="executeMethod"></param>
  89. /// <param name="canExecuteMethod"></param>
  90. public DelegateCommand(Action<object> executeMethod, Predicate<object> canExecuteMethod)
  91. {
  92. if (null == executeMethod)
  93. throw new ArgumentNullException("executeMethod");
  94.  
  95. this._executeMethod = executeMethod;
  96. this._canExecuteMethod = canExecuteMethod;
  97. }
  98.  
  99. public bool CanExecute(object parameter)
  100. {
  101. return (null == _canExecuteMethod) ? true : _canExecuteMethod(parameter);
  102. }
  103.  
  104. public event EventHandler CanExecuteChanged
  105. {
  106. add { CommandManager.RequerySuggested += value; }
  107. remove { CommandManager.RequerySuggested -= value; }
  108. }
  109.  
  110. public void Execute(object parameter)
  111. {
  112. _executeMethod(parameter);
  113. }
  114.  
  115. private Predicate<object> _canExecuteMethod;
  116. private Action<object> _executeMethod;
  117. }
  118.  
  119.  
  120. /// <summary>
  121. /// Expose the dictionary entries of a CommandMap as properties
  122. /// </summary>
  123. private class CommandMapDescriptionProvider : TypeDescriptionProvider
  124. {
  125. /// <summary>
  126. /// Standard constructor
  127. /// </summary>
  128. public CommandMapDescriptionProvider()
  129. : this(TypeDescriptor.GetProvider(typeof(CommandMap)))
  130. {
  131. }
  132.  
  133. /// <summary>
  134. /// Construct the provider based on a parent provider
  135. /// </summary>
  136. /// <param name="parent"></param>
  137. public CommandMapDescriptionProvider(TypeDescriptionProvider parent)
  138. : base(parent)
  139. {
  140. }
  141.  
  142. /// <summary>
  143. /// Get the type descriptor for a given object instance
  144. /// </summary>
  145. /// <param name="objectType">The type of object for which a type descriptor is requested</param>
  146. /// <param name="instance">The instance of the object</param>
  147. /// <returns>A custom type descriptor</returns>
  148. public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
  149. {
  150. return new CommandMapDescriptor(base.GetTypeDescriptor(objectType, instance), instance as CommandMap);
  151. }
  152. }
  153.  
  154. /// <summary>
  155. /// This class is responsible for providing custom properties to WPF - in this instance
  156. /// allowing you to bind to commands by name
  157. /// </summary>
  158. private class CommandMapDescriptor : CustomTypeDescriptor
  159. {
  160. /// <summary>
  161. /// Store the command map for later
  162. /// </summary>
  163. /// <param name="descriptor"></param>
  164. /// <param name="map"></param>
  165. public CommandMapDescriptor(ICustomTypeDescriptor descriptor, CommandMap map)
  166. : base(descriptor)
  167. {
  168. _map = map;
  169. }
  170.  
  171. /// <summary>
  172. /// Get the properties for this command map
  173. /// </summary>
  174. /// <returns>A collection of synthesized property descriptors</returns>
  175. public override PropertyDescriptorCollection GetProperties()
  176. {
  177. //TODO: See about caching these properties (need the _map to be observable so can respond to add/remove)
  178. PropertyDescriptor[] props = new PropertyDescriptor[_map.Commands.Count];
  179.  
  180. int pos = 0;
  181.  
  182. foreach (KeyValuePair<string, ICommand> command in _map.Commands)
  183. props[pos++] = new CommandPropertyDescriptor(command);
  184.  
  185. return new PropertyDescriptorCollection(props);
  186. }
  187.  
  188. private CommandMap _map;
  189. }
  190.  
  191. /// <summary>
  192. /// A property descriptor which exposes an ICommand instance
  193. /// </summary>
  194. private class CommandPropertyDescriptor : PropertyDescriptor
  195. {
  196. /// <summary>
  197. /// Construct the descriptor
  198. /// </summary>
  199. /// <param name="command"></param>
  200. public CommandPropertyDescriptor(KeyValuePair<string, ICommand> command)
  201. : base(command.Key, null)
  202. {
  203. _command = command.Value;
  204. }
  205.  
  206. /// <summary>
  207. /// Always read only in this case
  208. /// </summary>
  209. public override bool IsReadOnly
  210. {
  211. get { return true; }
  212. }
  213.  
  214. /// <summary>
  215. /// Nope, it's read only
  216. /// </summary>
  217. /// <param name="component"></param>
  218. /// <returns></returns>
  219. public override bool CanResetValue(object component)
  220. {
  221. return false;
  222. }
  223.  
  224. /// <summary>
  225. /// Not needed
  226. /// </summary>
  227. public override Type ComponentType
  228. {
  229. get { throw new NotImplementedException(); }
  230. }
  231.  
  232. /// <summary>
  233. /// Get the ICommand from the parent command map
  234. /// </summary>
  235. /// <param name="component"></param>
  236. /// <returns></returns>
  237. public override object GetValue(object component)
  238. {
  239. CommandMap map = component as CommandMap;
  240.  
  241. if (null == map)
  242. throw new ArgumentException("component is not a CommandMap instance", "component");
  243.  
  244. return map.Commands[this.Name];
  245. }
  246.  
  247. /// <summary>
  248. /// Get the type of the property
  249. /// </summary>
  250. public override Type PropertyType
  251. {
  252. get { return typeof(ICommand); }
  253. }
  254.  
  255. /// <summary>
  256. /// Not needed
  257. /// </summary>
  258. /// <param name="component"></param>
  259. public override void ResetValue(object component)
  260. {
  261. throw new NotImplementedException();
  262. }
  263.  
  264. /// <summary>
  265. /// Not needed
  266. /// </summary>
  267. /// <param name="component"></param>
  268. /// <param name="value"></param>
  269. public override void SetValue(object component, object value)
  270. {
  271. throw new NotImplementedException();
  272. }
  273.  
  274. /// <summary>
  275. /// Not needed
  276. /// </summary>
  277. /// <param name="component"></param>
  278. /// <returns></returns>
  279. public override bool ShouldSerializeValue(object component)
  280. {
  281. return false;
  282. }
  283.  
  284. /// <summary>
  285. /// Store the command which will be executed
  286. /// </summary>
  287. private ICommand _command;
  288. }
  289. }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement