Guest User

Untitled

a guest
Dec 11th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.18 KB | None | 0 0
  1. public class DelegateCommandListen : ICommand
  2. {
  3. private readonly List<WeakReference> _controlEvent;
  4. private Action<object> _executeDelegate;
  5.  
  6. public DelegateCommandListen(Action<object> executeDelegate, Predicate<object> canExecuteDelegate)
  7. {
  8. _controlEvent = new List<WeakReference>();
  9. ExecuteDelegate = executeDelegate;
  10. CanExecuteDelegate = canExecuteDelegate;
  11. }
  12.  
  13. public Predicate<object> CanExecuteDelegate { get; set; }
  14.  
  15. public Action<object> ExecuteDelegate
  16. {
  17. get { return _executeDelegate; }
  18. set
  19. {
  20. _executeDelegate = value;
  21. ListenForNotificationFrom((INotifyPropertyChanged) _executeDelegate.Target);
  22. }
  23. }
  24.  
  25. public void RaiseCanExecuteChanged()
  26. {
  27. if (_controlEvent != null && _controlEvent.Count > 0)
  28. _controlEvent.ForEach(ce => { ((EventHandler) ce.Target)?.Invoke(null, EventArgs.Empty); });
  29. }
  30.  
  31. public DelegateCommandListen ListenOn<TObservedType, TPropertyType>
  32. (TObservedType viewModel, Expression<Func<TObservedType, TPropertyType>> propertyExpression)
  33. where TObservedType : INotifyPropertyChanged
  34. {
  35. var propertyName = GetPropertyName(propertyExpression);
  36. viewModel.PropertyChanged += (s, e) =>
  37. {
  38. if (e.PropertyName == propertyName) RaiseCanExecuteChanged();
  39. };
  40. return this;
  41. }
  42.  
  43. public void ListenForNotificationFrom<TObservedType>(TObservedType viewModel)
  44. where TObservedType : INotifyPropertyChanged
  45. {
  46. viewModel.PropertyChanged += (s, e) => RaiseCanExecuteChanged();
  47. }
  48.  
  49. private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> expression)
  50. where T : INotifyPropertyChanged
  51. {
  52. var lambda = expression as LambdaExpression;
  53. var memberInfo = GetMemberExpression(lambda).Member;
  54. return memberInfo.Name;
  55. }
  56.  
  57. private static MemberExpression GetMemberExpression(LambdaExpression lambda)
  58. {
  59. MemberExpression memberExpression;
  60. if (lambda.Body is UnaryExpression body)
  61. {
  62. var unaryExpression = body;
  63. memberExpression = unaryExpression.Operand as MemberExpression;
  64. }
  65. else
  66. memberExpression = lambda.Body as MemberExpression;
  67. return memberExpression;
  68. }
  69.  
  70. public bool CanExecute(object parameter) => CanExecuteDelegate == null || CanExecuteDelegate(parameter);
  71.  
  72. public event EventHandler CanExecuteChanged
  73. {
  74. add
  75. {
  76. CommandManager.RequerySuggested += value;
  77. _controlEvent.Add(new WeakReference(value));
  78. }
  79. remove
  80. {
  81. CommandManager.RequerySuggested -= value;
  82. _controlEvent.Remove(_controlEvent.Find(r => (EventHandler) r.Target == value));
  83. }
  84. }
  85.  
  86. public void Execute(object parameter) => ExecuteDelegate?.Invoke(parameter);
  87. }
  88.  
  89. [TestMethod]
  90. public void NoTarget()
  91. {
  92. var sut = new DummyViewModel();
  93. Assert.IsFalse(sut.IsSelected);
  94. Assert.IsFalse(sut.ListenWithoutTargetCommand.CanExecute(null));
  95. sut.IsSelected = true;
  96. Assert.IsTrue(sut.ListenWithoutTargetCommand.CanExecute(null));
  97. }
  98.  
  99. public class DummyViewModel : INotifyPropertyChanged
  100. {
  101. private ICommand _listenWith1TargetCommand;
  102. private bool _isSelected;
  103.  
  104. public string Result { get; set; }
  105.  
  106. public bool IsSelected
  107. {
  108. get => _isSelected;
  109. set
  110. {
  111. if (value == _isSelected) return;
  112. _isSelected = value;
  113. OnPropertyChanged();
  114. }
  115. }
  116.  
  117. public ICommand ListenWith1TargetCommand
  118. {
  119. get
  120. {
  121. return _listenWith1TargetCommand ?? (_listenWith1TargetCommand = new DelegateCommandListen(
  122. s => { Result = "Executing listen command 1"; },
  123. s => IsSelected)
  124. .ListenOn(this, o => o.IsSelected));
  125. }
  126. }
  127.  
  128. public event PropertyChangedEventHandler PropertyChanged;
  129.  
  130. [NotifyPropertyChangedInvocator]
  131. protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  132. {
  133. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  134. }
  135. }
Add Comment
Please, Sign In to add comment