MVP ErrorControl 属性

MVP ErrorControl Property

我正在使用 MVP 模式将字段值从我的视图公开给我的演示者。我想在我的视图中添加一个 ErrorProvider 并添加来自 Presenter 的错误,但这将意味着公开我的控件,而我并不热衷于这样做。我的解决方案涉及创建一个 ExposableControlValue class,它一般公开一个值并具有添加的函数 CreateError(string errorMessage)

public interface IExposableControlValue<T>
{

  T Value { get; set; }

  void CreateError(string errorMessage);

  void ClearErrors();

}

我的想法是,我将通过引用传递 Property,现在我的通用值将基本上指向 Control 的支持字段。所有 ErrorProvider 逻辑都可以在视图端处理,所有错误检查都可以由演示者处理。

显然,我来这里是因为您无法通过引用传递 Property,而且我看到的所有示例都不够接近我的情况,因此我无法破译它们例子。

我也可以设置 T Get()Set(T value) 动态方法,如果有办法做到这一点,但简而言之,我想模仿 属性 'live' 在我的 class 实例中。

我会回答我自己的问题,因为我终于能够根据我的需要来解决这个问题。

使用工厂模式,我能够创建一个新方法CreateNew

  public IExposableControlValue<T> CreateNew<T>(ErrorProvider errorProvider, Control control, Func<T> get, Action<T> set) {
     var param1 = new ConstructorArgument("errorControl", errorProvider);
     var param2 = new ConstructorArgument("control", control);
     var exposableControlValue = resolutionRoot.Get<IExposableControlValue<T>>(param1, param2);
     exposableControlValue.CreateSet(set);
     exposableControlValue.CreateGet(get);

     return exposableControlValue;
  }

我正在使用 ninject,但概念是一样的。本质上,我要求用户提供一些依赖项来创建此 class 的新实例。然后,当我想真正公开内部通用值时,我会这样做:

  Func<T> get;

  Action<T> set;

  public ExposableControlValue(ErrorProvider errorControl, Control control) {
     ...configure my dependcies
  }

  public T Value { get { return get.Invoke(); } set { set.Invoke(value); } }

最后,当我实际使用工厂CreateNew方法时,我根据需要属性传入了一些参数

 _forSomethingBackingField = exposableControlFactory.CreateNew<decimal>(errorProvider, numericUpDownForSomething, 
        () => { return numericUpDownForSomething.Value; }, (decimal d) => { numericUpDownForSomething.Value = d; });

decimal 是我对 numeric up down 的通用值。如果您想使用 string 执行此操作,您只需使用 string 作为通用参数并将 (string s) = > someControlWithTextProperty.Text = s 传递给匿名方法参数。当然,这样做您需要确保您使用的 属性 实际上是您传递的类型。