Bind.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #if XFORMS
  2. namespace Caliburn.Micro.Core.Xamarin.Forms
  3. #else
  4. namespace Caliburn.Micro
  5. #endif
  6. {
  7. using System;
  8. #if WinRT
  9. using Windows.UI.Xaml;
  10. using Windows.UI.Xaml.Data;
  11. #elif XFORMS
  12. using global::Xamarin.Forms;
  13. using UIElement = global::Xamarin.Forms.Element;
  14. using FrameworkElement = global::Xamarin.Forms.VisualElement;
  15. using DependencyProperty = global::Xamarin.Forms.BindableProperty;
  16. using DependencyObject =global::Xamarin.Forms.BindableObject;
  17. #else
  18. using System.Windows;
  19. using System.Windows.Data;
  20. using Caliburn.Micro.Core;
  21. #endif
  22. /// <summary>
  23. /// Hosts dependency properties for binding.
  24. /// </summary>
  25. public static class Bind {
  26. /// <summary>
  27. /// Allows binding on an existing view. Use this on root UserControls, Pages and Windows; not in a DataTemplate.
  28. /// </summary>
  29. public static DependencyProperty ModelProperty =
  30. DependencyPropertyHelper.RegisterAttached(
  31. "Model",
  32. typeof(object),
  33. typeof(Bind),
  34. null,
  35. ModelChanged);
  36. /// <summary>
  37. /// Allows binding on an existing view without setting the data context. Use this from within a DataTemplate.
  38. /// </summary>
  39. public static DependencyProperty ModelWithoutContextProperty =
  40. DependencyPropertyHelper.RegisterAttached(
  41. "ModelWithoutContext",
  42. typeof(object),
  43. typeof(Bind),
  44. null,
  45. ModelWithoutContextChanged);
  46. internal static DependencyProperty NoContextProperty =
  47. DependencyPropertyHelper.RegisterAttached(
  48. "NoContext",
  49. typeof(bool),
  50. typeof(Bind),
  51. false);
  52. /// <summary>
  53. /// Gets the model to bind to.
  54. /// </summary>
  55. /// <param name = "dependencyObject">The dependency object to bind to.</param>
  56. /// <returns>The model.</returns>
  57. public static object GetModelWithoutContext(DependencyObject dependencyObject) {
  58. return dependencyObject.GetValue(ModelWithoutContextProperty);
  59. }
  60. /// <summary>
  61. /// Sets the model to bind to.
  62. /// </summary>
  63. /// <param name = "dependencyObject">The dependency object to bind to.</param>
  64. /// <param name = "value">The model.</param>
  65. public static void SetModelWithoutContext(DependencyObject dependencyObject, object value) {
  66. dependencyObject.SetValue(ModelWithoutContextProperty, value);
  67. }
  68. /// <summary>
  69. /// Gets the model to bind to.
  70. /// </summary>
  71. /// <param name = "dependencyObject">The dependency object to bind to.</param>
  72. /// <returns>The model.</returns>
  73. public static object GetModel(DependencyObject dependencyObject) {
  74. return dependencyObject.GetValue(ModelProperty);
  75. }
  76. /// <summary>
  77. /// Sets the model to bind to.
  78. /// </summary>
  79. /// <param name = "dependencyObject">The dependency object to bind to.</param>
  80. /// <param name = "value">The model.</param>
  81. public static void SetModel(DependencyObject dependencyObject, object value) {
  82. dependencyObject.SetValue(ModelProperty, value);
  83. }
  84. static void ModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  85. if (View.InDesignMode || e.NewValue == null || e.NewValue == e.OldValue) {
  86. return;
  87. }
  88. var fe = d as FrameworkElement;
  89. if (fe == null) {
  90. return;
  91. }
  92. View.ExecuteOnLoad(fe, delegate {
  93. var target = e.NewValue;
  94. d.SetValue(View.IsScopeRootProperty, true);
  95. #if XFORMS
  96. var context = fe.Id.ToString("N");
  97. #else
  98. var context = string.IsNullOrEmpty(fe.Name)
  99. ? fe.GetHashCode().ToString()
  100. : fe.Name;
  101. #endif
  102. ViewModelBinder.Bind(target, d, context);
  103. });
  104. }
  105. static void ModelWithoutContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  106. if (View.InDesignMode || e.NewValue == null || e.NewValue == e.OldValue) {
  107. return;
  108. }
  109. var fe = d as FrameworkElement;
  110. if (fe == null) {
  111. return;
  112. }
  113. View.ExecuteOnLoad(fe, delegate {
  114. var target = e.NewValue;
  115. var containerKey = e.NewValue as string;
  116. if (containerKey != null) {
  117. LogManager.GetLog(typeof(Bind)).Info("Using IoC is deprecated and will be removed in v3.0");
  118. target = IoC.GetInstance(null, containerKey);
  119. }
  120. d.SetValue(View.IsScopeRootProperty, true);
  121. #if XFORMS
  122. var context = fe.Id.ToString("N");
  123. #else
  124. var context = string.IsNullOrEmpty(fe.Name)
  125. ? fe.GetHashCode().ToString()
  126. : fe.Name;
  127. #endif
  128. d.SetValue(NoContextProperty, true);
  129. ViewModelBinder.Bind(target, d, context);
  130. });
  131. }
  132. /// <summary>
  133. /// Allows application of conventions at design-time.
  134. /// </summary>
  135. public static DependencyProperty AtDesignTimeProperty =
  136. DependencyPropertyHelper.RegisterAttached(
  137. "AtDesignTime",
  138. typeof(bool),
  139. typeof(Bind),
  140. false,
  141. AtDesignTimeChanged);
  142. /// <summary>
  143. /// Gets whether or not conventions are being applied at design-time.
  144. /// </summary>
  145. /// <param name="dependencyObject">The ui to apply conventions to.</param>
  146. /// <returns>Whether or not conventions are applied.</returns>
  147. #if NET
  148. [AttachedPropertyBrowsableForTypeAttribute(typeof(DependencyObject))]
  149. #endif
  150. public static bool GetAtDesignTime(DependencyObject dependencyObject) {
  151. return (bool)dependencyObject.GetValue(AtDesignTimeProperty);
  152. }
  153. /// <summary>
  154. /// Sets whether or not do bind conventions at design-time.
  155. /// </summary>
  156. /// <param name="dependencyObject">The ui to apply conventions to.</param>
  157. /// <param name="value">Whether or not to apply conventions.</param>
  158. public static void SetAtDesignTime(DependencyObject dependencyObject, bool value) {
  159. dependencyObject.SetValue(AtDesignTimeProperty, value);
  160. }
  161. static void AtDesignTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  162. if (!View.InDesignMode)
  163. return;
  164. var atDesignTime = (bool) e.NewValue;
  165. if (!atDesignTime)
  166. return;
  167. #if XFORMS
  168. d.SetBinding(DataContextProperty, String.Empty);
  169. #else
  170. BindingOperations.SetBinding(d, DataContextProperty, new Binding());
  171. #endif
  172. }
  173. static readonly DependencyProperty DataContextProperty =
  174. DependencyPropertyHelper.RegisterAttached(
  175. "DataContext",
  176. typeof(object),
  177. typeof(Bind),
  178. null, DataContextChanged);
  179. static void DataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  180. if (!View.InDesignMode)
  181. return;
  182. var enable = d.GetValue(AtDesignTimeProperty);
  183. if (enable == null || ((bool)enable) == false || e.NewValue == null)
  184. return;
  185. var fe = d as FrameworkElement;
  186. if (fe == null)
  187. return;
  188. #if XFORMS
  189. ViewModelBinder.Bind(e.NewValue, d, fe.Id.ToString("N"));
  190. #else
  191. ViewModelBinder.Bind(e.NewValue, d, string.IsNullOrEmpty(fe.Name) ? fe.GetHashCode().ToString() : fe.Name);
  192. #endif
  193. }
  194. }
  195. }