泛型类作为非泛型类中的属性

时间:2019-06-13 06:51:51

标签: c# .net winforms generics gridview

我有一个自定义GridView,我想设置一些显示错误的规则。 我想做这样的事情:

var grid = new MyGridView();
grid.DataSource = new List<MyClass>();
grid.InitErrorRegistrator<MyClass>()
   .RegisterRule(column1, x => x.Property1 == 12)
   .RegisterRule(column2, x => x.Property2 == "Test");

因此,当我填充网格时,我期望在用不适当的值填充行值时看到错误。

我有这样的东西:


internal class ErrorRegistrator
{
   internal GenericErrorRegistrator<T> Init<T>()
   {
      return new GenericErrorRegistrator<T>();
   }

   /*Here I think I could use methods to get values from GenericErrorRegistrator<T> dictionary like:*/
   internal bool CheckRule(string column, object row)
   {
      return GenericErrorRegistrator.CheckRule(column, row);
   }
}

public class GenericErrorRegistrator<T>
{
   private readonly Dictionary<string, object> _errorRules = new Dictionary<string, object>();
   internal Dictionary<string, object> ErrorRules => _errorRules;

   public void RegisterErrorRule(string columnName, Func<T, bool> func)
   {
      _errorRules.Add(columnName, func);
   }
   public bool CheckRule(string column, object row)
   {
       Func<T, bool> func = _errorRules[column]
       return func((T) row);  
   }
}

MyGridView

public class MyGridView : GridView
{
    internal ErrorRegistrator ErrorRegistrator = new ErrorRegistrator();

/*Here I think should be something like*/
    public GenericErrorRegistrator<T> InitErrorRegistrator<T>()
    {
        return ErrorRegistrator.Init<T>();
    }

}

最后,我有一个GridController类,该类分析是否存在任何规则并将其应用于行:

public class MyGridCurrencyDataController : CurrencyDataController
{
   public override ErrorInfo GetErrorInfo(int controllerRow, int column)
   {
      var info = base.GetErrorInfo(controllerRow, column);
      DataColumnInfo dataColumnInfo = Columns[column];
      BandedGridColumn gridColumn = GridColumns.ColumnByFieldName(dataColumnInfo.Name);

      if (HasErrRules ?? false)
      {
        object row = _view.GetRow(controllerRow);
        /*I think here I need something like this*/
        bool showError = _view.ErrorRegistrator.CheckRule(gridColumn.Name, row );                       
        if (showError)
           SetError(new RowColumnErrorEventArgs(info, controllerRow, gridColumn));
        else
           ClearError(new RowColumnErrorEventArgs(info, controllerRow, gridColumn));
       }
       _view.FillRowColumnError(controllerRow, gridColumn, info);
       return info;
     }
}

我如何实现这一目标,这有可能吗?

1 个答案:

答案 0 :(得分:0)

这就是我所拥有的。稍后我将测试性能,但是至少可以。

myGridView.InitRegistrator<Job>()
   .RegisterRule(column1, x => string.IsNullOrEmpty(x.Code))
   .RegisterRule(column2, x => string.IsNullOrEmpty(x.Name))

MyGridView

public class MyGridView : GridView
{
   internal ErrorRegistrator ErrorRegistrator = new ErrorRegistrator();
   public GenericErrorRegistrator<T> InitRegistrator<T>(params Func<T, bool>[] funcs)
   {
      return ErrorRegistrator.Init<T>();
   }
}

ErrorRegistrator

    internal class ErrorRegistrator
    {
        internal bool HasRules => _registrator.HasRules();

        private BaseGenericErrorRegistrator _registrator;
        internal GenericErrorRegistrator<T> Init<T>()
        {
            var errorRegistrator = new GenericErrorRegistrator<T>();
            _registrator = errorRegistrator;
            return errorRegistrator;
        }

        public bool CheckRule(string columnName, object row)
        {
            return _registrator.CheckRule(columnName, row);
        }
    }

    public abstract class BaseGenericErrorRegistrator
    {
        internal abstract bool HasRules();
        internal abstract bool CheckRule(string columnName, object row);
    }

    public class GenericErrorRegistrator<T> : BaseGenericErrorRegistrator
    {
        private readonly Dictionary<string, Func<T, bool>> _rules = new Dictionary<string, Func<T, bool>>();
        public GenericErrorRegistrator<T> RegisterRule(string columnName, Func<T, bool> func)
        {
            _rules.Add(columnName, func);
            return this;
        }

        internal override bool HasRules()
        {
            return _rules.Any();
        }

        internal override bool CheckRule(string columnName, object row)
        {
            return _rules.TryGetValue(columnName, out Func<T, bool> func) && func((T) row);
        }
    }

然后我可以使用ErrorRegistrator字段检查规则