CallExtension.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Windows.Markup;
  3. using System.Windows;
  4. using System.Windows.Data;
  5. using System.Windows.Input;
  6. using System.Reflection;
  7. namespace FWindSoft.MVVM
  8. {
  9. public class CallExtension : MarkupExtension
  10. {
  11. private string m_MethodName;
  12. public CallExtension(string methodName)
  13. {
  14. this.m_MethodName = methodName;
  15. }
  16. public override object ProvideValue(IServiceProvider serviceProvider)
  17. {
  18. var t = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
  19. return new CallCommand(t.TargetObject as FrameworkElement, m_MethodName);
  20. }
  21. }
  22. public class CallCommand : DependencyObject, ICommand
  23. {
  24. #region 私有字段
  25. private FrameworkElement m_Element;
  26. private string m_MethodName;
  27. private MethodInfo m_Method;
  28. #endregion
  29. public CallCommand(FrameworkElement element, string methodName)
  30. {
  31. this.m_Element = element;
  32. this.m_MethodName = methodName;
  33. element.DataContextChanged += target_DataContextChanged;
  34. BindingOperations.SetBinding(this, CanCallProperty, new Binding("DataContext.Can" + methodName)
  35. {
  36. Source = element
  37. });
  38. GetMethod();
  39. }
  40. public static readonly DependencyProperty CanCallProperty =
  41. DependencyProperty.Register("CanCall", typeof(bool), typeof(CallCommand),
  42. new PropertyMetadata(true));
  43. public bool CanCall
  44. {
  45. get { return (bool)GetValue(CanCallProperty); }
  46. set { SetValue(CanCallProperty, value); }
  47. }
  48. public object DataContext
  49. {
  50. get { return m_Element.DataContext; }
  51. }
  52. protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  53. {
  54. base.OnPropertyChanged(e);
  55. if (e.Property == CanCallProperty)
  56. {
  57. RaiseCanExecuteChanged();
  58. }
  59. }
  60. void GetMethod()
  61. {
  62. m_Method = DataContext == null ? null : DataContext.GetType().GetMethod(m_MethodName, Type.EmptyTypes);
  63. }
  64. void target_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  65. {
  66. GetMethod();
  67. RaiseCanExecuteChanged();
  68. }
  69. void RaiseCanExecuteChanged()
  70. {
  71. if (CanExecuteChanged != null)
  72. {
  73. CanExecuteChanged(this, EventArgs.Empty);
  74. }
  75. }
  76. #region ICommand Members
  77. public event EventHandler CanExecuteChanged;
  78. public bool CanExecute(object parameter)
  79. {
  80. return m_Method != null && CanCall;
  81. }
  82. public void Execute(object parameter)
  83. {
  84. object[] arrays = new object[1] {parameter};
  85. m_Method.Invoke(DataContext,arrays);
  86. }
  87. #endregion
  88. }
  89. }