This is a migrated thread and some comments may be shown as answers.

Hiding table column and adjusting other columns

15 Answers 1337 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Aaron
Top achievements
Rank 1
Aaron asked on 11 Dec 2012, 09:43 PM
I have a table that has a column that may or not be visible. When it isn't visible I then need to adjust the proceeding 2 columns, one to put in the now invisible column's space and the second to increase its width. I have been able to get the column to be invisible via formatting but am not sure how to move and adjust the other columns. I had the same issue with rows and had to create a table for each row and keep track of the visibility and location of each row myself.

15 Answers, 1 is accepted

Sort by
0
Elian
Telerik team
answered on 14 Dec 2012, 03:09 PM
Hi Aaron,

Telerik Reporting is a data driven solution. Thus to hide certain table columns our suggestion is to use a group filter. To explore the table groups, please open the group explorer in extended mode. When hiding a column with filters the rest of the columns will automatically move to the left and take the space that the hidden column should have occupied. 

As to the spacing - you can manually adjust the columns widths only before the table is processed. This can be done by changing the definition of the table. You should shrink the following items:
  1. The table itself 
  2. The table's body column
  3. All the items contained inside the corresponding column
Refer to the following sample code:
private void table1_ItemDataBound(object sender, EventArgs e)
{
    //adjust the overall width
    this.table1.Width = this.table.Width - ...
    //adjust the body column
    this.table1.Body.Columns(2).Width = <new_size>;
    //...
    //adjust all the items in the corresponding column
    this.textBox4.Width = <new_size>;
    //...
    //and so on...
}

Regards,
Elian
the Telerik team

HAPPY WITH REPORTING? Do you feel that it is fantastic? Or easy to use? Or better than Crystal Reports? Tell the world, and help fellow developers! Write a short review about Telerik Reporting and Telerik Report Designer in Visual Studio Gallery today!

0
Aaron
Top achievements
Rank 1
answered on 04 Feb 2013, 09:30 PM
This works great when deleting a row with only one column, but how would you go about removing a row with multiple columns? Setting all textboxes' height to 0 does not do the job and the entire row remains visible. Does the column and row grouping have anything to do with this?

Thanks.
0
Steven
Top achievements
Rank 1
answered on 05 Feb 2013, 03:58 AM
Just create an iterator that loops the table cells and then set the Height or Width to your desired measurement.

If you are adjusting a column, then you need to adjust the Column Width, Table Width and then every cell in that index, even those columns that span the target index.

You can merge these extension methods into a single helper method to do what you need, but these are a part of my extension library that has a bunch of Telerik tweeks.

MODERATOR - Are there any community driven open source Telerik extensions?


/// <summary>
/// ItemDataBinding, Remove columns by settings its width to Zero
/// </summary>
/// <param name="tableDef"></param>
/// <param name="columnIndexes"></param>
public static void CollapseColumns(this Telerik.Reporting.Table tableDef, params int[] columnIndexes)
{
    var cells = tableDef.Body.Where(x => x.ReportItem != null).ToList();
    int columnLength = tableDef.Body.Columns.Count;
 
    for (var i=0; i < columnLength; i++)
    {
        if (columnIndexes.Contains(i))
        {
            var column = tableDef.Body.Columns[i];               
            cells.FindByColumn(i).AdjustWidth(column.Width, false);
            tableDef.Width = tableDef.Width.Subtract(column.Width);
            column.Width = zero;
        }
    }
}
 
 
 
/// <summary>
/// ItemDataBinding, Get cells for matching column or in colSpan
/// </summary>
/// <param name="tableDef"></param>
/// <param name="columns"></param>
public static IEnumerable<Telerik.Reporting.TableCell> FindByColumn(this IEnumerable<Telerik.Reporting.TableCell> cells, params int[] columnIndexes)
{
    foreach (int index in columnIndexes)
        foreach (var cell in cells.Where(x => x.ColumnIndex <= index && (x.ColumnIndex + x.ColumnSpan - 1) >= index))
            yield return cell;
}
 
public static void AdjustWidth(this IEnumerable<Telerik.Reporting.TableCell> cells, Telerik.Reporting.Drawing.Unit unit, bool add = true)
{
    UnitFunc unitFunc = x => (add) ? x.Add(unit) : x.Subtract(unit);
 
    foreach (var cell in cells.Where(x => x.ReportItem != null).ToArray())
    {
        var newWidth = unitFunc(cell.ReportItem.Width);
        if (newWidth.Value <= almostZero)
            newWidth = zero;
 
        if (newWidth.Value < cell.ReportItem.Width.Value && cell.ReportItem is Telerik.Reporting.TextItemBase)
            ((Telerik.Reporting.TextItemBase)cell.ReportItem).CanGrow = false; // value is still populated
 
        cell.ReportItem.Width = newWidth;
    }
}


Same logic would be applied to Row Height but you have to use reflection to set the Row Height in Millimeters


private static PropertyInfo RowHeightProperty = typeof(Telerik.Reporting.Processing.TableRow).GetProperty("Height", BindingFlags.Instance | BindingFlags.NonPublic);
 
        
/// <summary>
/// Collapse Rows that matches predicate
/// </summary>
/// <param name="table"></param>
/// <param name="cellCheck"></param>
public static void CollapseRows(this Telerik.Reporting.Processing.Table table, Func<Telerik.Reporting.Processing.ITableCell, bool> cellCheck = null)
{
    Telerik.Reporting.Processing.ITableCell cell;
 
    if (cellCheck == null) cellCheck = x => true;
    int cLen = table.Columns.Count;
    int rLen = table.Rows.Count;
    Telerik.Reporting.Drawing.Unit height;
             
    for (var r=0; r < rLen; r++)
    {
        var row = table.Rows[r];
 
        cell = null;
        for(int c = 0; c < cLen; c += cell.ColumnSpan)
        {
            cell = row.GetCell(c);
            if (cell.RowIndex == r && cellCheck(cell))
            {
                height = Telerik.Reporting.Drawing.Unit.Mm(RowHeightProperty.GetValue(row, null).ChangeType<double>());
 
                cell = null;
                for (int i = 0; i < cLen; i += cell.ColumnSpan)
                {
                    cell = row.GetCell(i);
                    if (cell.RowIndex == r)
                    {
                        cell.Item.Visible = false;
                    }
                    // else
                    // {
                    //     cell.Item.Height = cell.Item.Height.Subtract(height);
                    // }
                }
 
                RowHeightProperty.SetValue(row, 0D, null);
                         
                break;
            }
        }
    }                      
}
0
Massimiliano Bassili
Top achievements
Rank 1
answered on 05 Feb 2013, 10:15 AM
Steven, you can use the code library section (http://www.telerik.com/community/code-library/reporting/general.aspx) to post extensions/projects that the community can benefit from.

Cheers!
0
Aaron
Top achievements
Rank 1
answered on 05 Feb 2013, 05:44 PM
Your code did not work for me...

So if the following code works for a row with one column, why wouldn't it work for multiple columns?

 public static void RemoveTableRow(Table table, int rowIndex, params ReportItem[] textBoxesToRemove)
        {
            Unit height = textBoxesToRemove[0].Height;
            foreach (var textBox in textBoxesToRemove)
            {
                textBox.Height = new Unit(0, UnitType.Inch);
            }
            table.Body.Rows[rowIndex].Height = new Unit(0, UnitType.Inch);
            table.Height -= height;
        }
0
Hadib Ahmabi
Top achievements
Rank 1
answered on 08 Feb 2013, 08:34 AM
Why would you need to remove rows? That's what filters are for.
0
Aaron
Top achievements
Rank 1
answered on 08 Feb 2013, 05:54 PM
Ok, so without using filters. If I can remove a row that has one column using that logic why can I not remove a row with multiple columns?

Using Steven's code does not remove the row and then causes a few more issues.
0
Steven
Top achievements
Rank 1
answered on 08 Feb 2013, 07:50 PM
It depends on what stage of the report lifecycle your in.

Within the Reports ItemDataBinding event you can load your data and manually set the visibility of static rows and static columns.

While the table rows are binding, you'll have to use the table filters

After the table is bound, you could provide cleanup by collapsing the row and textboxes within the row cells.

Within the bound event it already has populated the table cells with data and changing visibility at this stage will cause the rendering extensions to crash.


The code I provided was to Collapse the row after its data has been populated because sometime you just don't have the data available to determine where to suppress the row during its binding event since you only have access to Static Methods and the Binding DataObject.

If I have a static row and a horizontal group, I may need to hide a row if all the row values are zero,
I can set the rows visibility within the Reports ItemDataBinding event if I manually get my data before the table binds, but if I can't then I can just cleanup after the tables bound.

The table becomes the definition for the processing element, so updating fields after the processing object has been generated won't work and blows up if you change visibility.


I also use this in a report that has a dozen different configuration settings and I collapse certain rows and resize others to take up the slack.   These reports also have very complex logic on how a value should be formatted, rounded, precision and whether zeros should be suppressed.    You can apply this in a Binding or Bound event to every cell, but I find it easier to iterate that table within its ItemDataBound event.


I'm not providing you a finished solution for your problem, I'm providing ideas on how you can tweak the report outside of the existing logic points.

Use the debugger and JustCode to see what properties you can adjust out of cycle.
0
Robert
Top achievements
Rank 1
answered on 15 Jan 2016, 09:57 PM

I realize this is an old post.  I have not used these forums before, so I'm not sure if I should expect a response.

I have a very similar situation where I wish to conditionally remove a column and have the other columns re-size. You (Admin) seem to suggest that by filtering the column group using the extended group editor functionality, the columns will re-size themselves to some extent. However, you mention that the filtered column will cause the columns to the right to move to the left. I need the opposite: I need to conditionally hide the last column on the right in my table, and have the column to the left grow horizontally to take up the space of the filtered column. Is this possible without resorting to writing code to adjust the widths? 

0
Nasko
Telerik team
answered on 19 Jan 2016, 01:40 PM
Hello Robert,

The Table item does not offer an option to reclaim space from hidden columns automatically. However, it is possible to assign a binding to another column, which sets the Width property of the whole column to a larger than the current value.

Regards,
Nasko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Robert
Top achievements
Rank 1
answered on 19 Jan 2016, 03:59 PM

Thank you. Is it better to use the forums when asking questions like these? Or is it better to use your Ticket System?

Will a member of the support team answer forum in quires? 

0
Nasko
Telerik team
answered on 20 Jan 2016, 12:13 PM
Hello Robert,

We recommend posting the same question multiple times, in order not to split information between threads and handle your question more precisely.
If it is an emergency use our support ticketing system as this is the best way to reach our support staff - the support system assigns a response time for all of your questions, depending on your license and ensures that all questions will reach the respective developers if needed.
You can post your questions in the forums when you don't need an urgent answer and you want to help the community as well. The forums are community driven and as such we do not guarantee that a support team member will always be there to answer all of the queries.

Regards,
Nasko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Daniel
Top achievements
Rank 1
answered on 10 Jun 2020, 12:46 PM

Hi,

I have a table which displays a list of items where I hide columns using a filter and thereafter adjust the width of the visible columns with a binding to a user function which determines the width.

The solution works fine when the table contains data. However if there is no data to show in the table, the columns are not resized.

I want to resize the columns also when an empty list is passed to the table so the table is always the same width. How can I achieve this?

0
Todor
Telerik team
answered on 15 Jun 2020, 08:39 AM

Hi Daniel,

I confirm the observed behavior. When the data source of the table is empty, there will be no detail section rendered. Probably the Bindings are not respected properly in this case. I have logged the issue for further investigation in our public feedback portal - When a Table has no data, the Binding of its column width is not respected. We have also updated your Telerik points as a token of gratitude.

As a workaround, you may test to set the required Table column widths for an empty Table as the default width values.

Regards,
Todor
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Daniel
Top achievements
Rank 1
answered on 15 Jun 2020, 12:39 PM

I updated my method for getting the correct columns. Instead of creating all possible columns and filtering them I only add the wanted columns dynamically and set their width in a for-loop as described by Silviya in https://www.telerik.com/forums/how-to-create-a-table-in-telerik-report-with-dynamic-columns-from-sql-stored-procedure#3c3oM6D0wE2G5wglX7nnNg from the tables ItemDataBinding event.

This method generates less code and is easier to handle. It has the drawback that I cannot apply formatting to specific columns which I had to solve by saving values as strings with the correct format instead of as decimals. I guess you could do something in the for-loop to add formatting to specific columns but I do not like the thought of that approach. Further it is not as intuitive for some other developer who will look at the table in the report designer when you cannot se any columns in the table.

Anyway, thanks for answering! An answer stating that it is not possible is much better than no answer.

Tags
General Discussions
Asked by
Aaron
Top achievements
Rank 1
Answers by
Elian
Telerik team
Aaron
Top achievements
Rank 1
Steven
Top achievements
Rank 1
Massimiliano Bassili
Top achievements
Rank 1
Hadib Ahmabi
Top achievements
Rank 1
Robert
Top achievements
Rank 1
Nasko
Telerik team
Daniel
Top achievements
Rank 1
Todor
Telerik team
Share this question
or