PageRenderTime 80ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/source/library/Interlace/Binding/PropertyBinderModel.cs

https://bitbucket.org/VahidN/interlace
C# | 184 lines | 120 code | 39 blank | 25 comment | 24 complexity | 61f6b33b014a5d1698fff689fa7ddb1a MD5 | raw file
  1. #region Using Directives and Copyright Notice
  2. // Copyright (c) 2007-2010, Computer Consultancy Pty Ltd
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above copyright
  10. // notice, this list of conditions and the following disclaimer in the
  11. // documentation and/or other materials provided with the distribution.
  12. // * Neither the name of the Computer Consultancy Pty Ltd nor the
  13. // names of its contributors may be used to endorse or promote products
  14. // derived from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. // ARE DISCLAIMED. IN NO EVENT SHALL COMPUTER CONSULTANCY PTY LTD BE LIABLE
  20. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  26. // DAMAGE.
  27. using System;
  28. using System.ComponentModel;
  29. using System.Collections.Generic;
  30. using System.Text;
  31. using System.Reflection;
  32. #endregion
  33. namespace Interlace.Binding
  34. {
  35. class PropertyBinderModel : Interlace.Binding.IBinderModel
  36. {
  37. private string _propertyName;
  38. object _boundTo;
  39. Type _boundToType;
  40. bool _ignoreChangedEvent;
  41. private BinderController _controller;
  42. public PropertyBinderModel(string propertyName)
  43. {
  44. _propertyName = propertyName;
  45. _boundTo = null;
  46. _ignoreChangedEvent = false;
  47. }
  48. public BinderController Controller
  49. {
  50. set { _controller = value; }
  51. }
  52. public string GetDescriptionForTracing()
  53. {
  54. if (_boundTo == null) return string.Format(
  55. "Property \"{0}\" of null", _propertyName);
  56. return string.Format("Property \"{0}\" of \"{1}\", type \"{2}\"",
  57. _propertyName, _boundTo, _boundToType.Name);
  58. }
  59. private void ConnectEvents()
  60. {
  61. EventInfo changeEvent = _boundToType.GetEvent(_propertyName + "Changed");
  62. if (changeEvent != null)
  63. {
  64. changeEvent.AddEventHandler(_boundTo, new EventHandler(ChangedEventHandler));
  65. }
  66. else
  67. {
  68. if (_boundTo is INotifyPropertyChanged)
  69. {
  70. INotifyPropertyChanged notifier = _boundTo as INotifyPropertyChanged;
  71. notifier.PropertyChanged += new PropertyChangedEventHandler(PropertyChangedEventHandler);
  72. }
  73. }
  74. }
  75. private void DisconnectEvents()
  76. {
  77. EventInfo changeEvent = _boundToType.GetEvent(_propertyName + "Changed");
  78. if (changeEvent != null)
  79. {
  80. changeEvent.RemoveEventHandler(_boundTo, new EventHandler(ChangedEventHandler));
  81. }
  82. else
  83. {
  84. if (_boundTo is INotifyPropertyChanged)
  85. {
  86. INotifyPropertyChanged notifier = _boundTo as INotifyPropertyChanged;
  87. notifier.PropertyChanged -= new PropertyChangedEventHandler(PropertyChangedEventHandler);
  88. }
  89. }
  90. }
  91. public void ConnectBoundToObject(object boundTo)
  92. {
  93. if (_boundTo != null)
  94. {
  95. DisconnectEvents();
  96. }
  97. _boundTo = boundTo;
  98. _boundToType = boundTo.GetType();
  99. ConnectEvents();
  100. _controller.OnModelModified();
  101. }
  102. public void DisconnectBoundToObject()
  103. {
  104. if (_boundTo != null)
  105. {
  106. DisconnectEvents();
  107. }
  108. _boundTo = null;
  109. _boundToType = null;
  110. _controller.OnModelModified();
  111. }
  112. private void ChangedEventHandler(object sender, EventArgs e)
  113. {
  114. if (_ignoreChangedEvent) return;
  115. _controller.OnModelModified();
  116. }
  117. void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
  118. {
  119. if (_ignoreChangedEvent) return;
  120. if (e.PropertyName == _propertyName) _controller.OnModelModified();
  121. }
  122. public object GetValue()
  123. {
  124. if (_boundTo == null) return BinderNotBound.Value;
  125. PropertyInfo property = _boundToType.GetProperty(_propertyName);
  126. if (property == null) return BinderMissingProperty.Value;
  127. return property.GetValue(_boundTo, null);
  128. }
  129. public void SetValue(object value)
  130. {
  131. if (_boundTo == null) return;
  132. PropertyInfo property = _boundToType.GetProperty(_propertyName);
  133. if (property == null) return;
  134. try
  135. {
  136. _ignoreChangedEvent = true;
  137. property.SetValue(_boundTo, value, null);
  138. }
  139. finally
  140. {
  141. _ignoreChangedEvent = false;
  142. }
  143. }
  144. }
  145. }