ReportViewer 2010努力应对多态性 [英] ReportViewer 2010 struggling with polymorphism

查看:96
本文介绍了ReportViewer 2010努力应对多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个rdlc报表,它以List<BaseClass>作为ReportDataSource. BaseClass具有两个派生类AB.
在报告中,我基于基类的属性进行分组.只要列表仅包含AB的对象,所有列表都可以正常工作.但是,如果我混合了AB的实例,则报告创建将失败,并显示以下消息:

I have a rdlc report that takes as a ReportDataSource a List<BaseClass>. BaseClass has two derived classes A and B.
In the report, I group based on a property of the base class. As long as the list only contains objects of A or B, all works fine. However if I mix instances from A and B, then the report creation fails with the following message:

用于对"[Group Name]"进行分组的Group表达式引用了一个包含错误的数据集字段:FieldValueException

对于这两个类,该属性都返回一个简单的字符串文字,并由这些类的常量作为后盾,这没有什么不对的.我还检查了所有其他使用的属性,但是它们没有任何问题.
有没有其他人看到过这种行为或有人对此行为进行了移植?在我看来,报表查看器不喜欢多态!可以吗?

The property returns for both classes a simple string literal, backed by a constant of the classes, there is nothing that could be wrong with this. I also checked all other used properties, but there is nothing wrong with them.
Has anybody else seen this behaviour or has someone an explantion for this behaviour? It seems to me that report viewer don't likes polymorphism! Could that be?

示例

public abstract class BaseClass{
   public abstract string GroupKey{get;}
}
public class A : BaseClass{
    public override string GroupKey{
       get{
          return ...
       }
    }
}
public class B : BaseClass{
    public override string GroupKey{
       get{
          return ...
       }
    }
}

推荐答案

原来,这是另一个

It turned out that this is another limitation of Report Viewer. As a solution I have created a class C that derives also from BaseClass and wrapps an instance of BaseClass.
Before providing my List<BaseClass> as a DataSource for Report Viewer, I wrap all contained instances of A and B with an instance of C and give then the list of C to Report Viewer. So all instances are of the same type and Report Viewer is happy.

这里是一个例子.我希望这对处于相同情况的人有所帮助:

public abstract class BaseClass{
   public string GroupKey{get;}
   public virtual C GetWorkaroundWrapper(){
       return new C(this);
   }
}
public class A : BaseClass{
    public override string GroupKey{
       get{
          return ...
          }
    }
}
public class B : BaseClass{
    public override string GroupKey{
       get{
          return ...
          }
    }
}
public class C : BaseClass{
    BaseClass m_baseClass;
    public C(BaseClass baseClass){
         if(null == baseClass){
             throw new ArgumentNullException("baseClass");
         }
         m_baseClass=baseClass;
    }
    public override string GroupKey{
         get{
             return m_baseCLass.GroupKey;
         }
    }
    public override C GetWorkaroundWrapper(){
         return this;
    }
}

GetWorkaroundWrapper-方法仅是为了方便.这样,就简化了包装器的创建:

The GetWorkaroundWrapper-Methodis only for convenience. With this, the creation of the wrapper is simplified:

List<C> workaroundList=new List<C>();
foreach(BaseClass item in sourceList){
 workaroundList.Add(item.GetWorkaroundWrapper());
}

dataSource.Value=workaroundList;

请注意,列表是否为C并不重要.它也可以与BaseClass列表一起使用,但是使用C列表更干净.

Please note that it is not important that the list is of C. It works also with a list of BaseClass, but its more clean to use a list of C.

这篇关于ReportViewer 2010努力应对多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆