I have a List item on my report which is bound to a DB table. If the List's data source is empty (returns no results), the List item is still generated and on the report the List takes up as much empty space as the List item takes up on the layout in the Designer. I would prefer if the List's data source is empty, that the List item should not even render and any Report items below it should move up to fill its space. Is this possible to achieve?
My problem is particularly severe:
My List is composed of only 3 items - 1 PictureBox to display an image, one TextBox to display the image title, and another TextBox to display a caption for the image.
However, the List is sized quite large to accomodate the PictureBox, the latter of which is 6 in. W x 7 in. H. Consequently, one of these List items intentionally accomodates an entire 8.5x11 page when the report is generated.
So you see, my problem is should the data source for the List return no results, my List item - given its large dimensions in the Report Designer - still generates a very large empty white space in my report (an entirely blank page in this case). This looks especially silly because the List item is preceeded and followed by other Report Items which contain actual data.
6 Answers, 1 is accepted
As you've figured out, there is no out of the box solution for this. There are two options:
- check if your datasource returns data and in case it doesn't, set the Visible property of the List to false.
- set minimum height of the nested items and List item itself, so that when there is no data it would not take any space. When there is data, the report items would grow and accommodate the space they need.
the Telerik team
- Regarding your first point - Originally I thought the Visible property was my solution. But setting Visible=False when applied to a TextBox, for instance, simply turns the TextBox area into white space in the report. The white space occupies as much space as the TextBox does in the layout and at the same location. The other items in the report do not shift to fill the space where the TextBox is, even though I expected them to do so. Now, in the case of setting my List's Visible=False, I get some weird behavior: The List appears not to be rendered at its location in the report layout. However, for some reason I get a massive area of white space (an extra page) appended to the end of my report. So instead of the List being rendered at its Designer location, it appears the full area of the List (as laid out in the Designer) is being turned into white space appended to the end of the report. Strange.
- I haven't tried your second option yet.
- I was wondering if another option would be to dynamically create and place my Report items based on some values in the data source. Could you direct me to an example of doing such? For instance, if my data source contains a certain value, based on that value I would dynamically add X kind of items to the report or Y kind of items to the report. I'm not certain during which events I would do this or how I would access my data source at that time to test its values. For instance, in my case I would not add a List at design time. At run time, if my List data source is empty, I would not add a List, but I would dyamically append to my report all items which come after the List. And if my List data source was not empty, I would dymically append the List and all items which follow the List.
My List datasource is bound to a SqlDataAdapter in the designer.
How and when can I check if the datasource is empty?
I see in InitializeComponent() that the SqlDataAdapter is assigned directly to the List.DataSource. (There doesn't seem to be a DataSet involved)
Immediately after the InitializeComponent() call, I try to check if the List is empty, but I can't find a way to access the datasource to check if it is empty.
Because the List.DataSource is bound directly to a SqlDataAdapter, there doesn't seem have been a DataSet involved or seems there is no way to access it. And there seems to be no property in the List object which simply tells you how many items (i.e. datasource rows, not number report items) are in the List.
What am I missing?
Indeed you would not be able to make this check through the report designer or in its constructor. You can however wire up the NeedDataSource event of the table item, create a dataset, fill it and check against it e.g.:
private void list1_NeedDataSource(object sender, EventArgs e)
Telerik.Reporting.Processing.Table procList = (Telerik.Reporting.Processing.Table)sender;
string sql = @"SELECT Production.Product.Name, Production.Product.ProductNumber FROM Production.Product";
string connectionString = "Data Source=(local)\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True";
SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
DataSet dataSet = new DataSet();
if (dataSet.Tables.Rows.Count != 0)
procList.Visible = false;
procList.DataSource = dataSet;
Hope this helps.
the Telerik team
During debug I drilled down into the objects, checked the variable values, and realized the ChildElements.Count (see below) seemed to correspond to the number of rows in the list's data source. Interestingly, during the debug inspection, I noticed the list (actually a Table in this case) contains a Rows property, but it is marked as a Non-Public Member in the class. Intuitively speaking, that Rows property would be just what I need to check its count. Not sure why you guys make it inaccessible, but you must have a good reason. Fortunately, ChildElements.Count tells me the same thing in this case.
private void list_ItemDataBound(object sender, EventArgs e)
Telerik.Reporting.Processing.Table list = (Telerik.Reporting.Processing.Table)sender;
if (list.ChildElements.Count == 0)
// list is empty
// list is not empty