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

Adjusting Column Width with Reflection

2 Answers 342 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Steven
Top achievements
Rank 1
Steven asked on 21 Dec 2012, 05:16 AM
I'm attempting to adjust the column width programatically and from other forum posts I've read that there is allot involved.

I can Hide Column content on ItemDataBound, but I cannot collapse the width.
Using JustCompile and the debugger I believe I'm setting all the proper widths, but I cannot get it to collapse.

below is my code.
Can you provide any insight on the events between ItemDataBound and rendering and if there is an event between where I can adjust these values.  
public static void RemoveColumns(this Telerik.Reporting.Table tableDef, params int[] columns)
{
    /*
    var colGroups = Flatten(tableDef.ColumnGroups).ToList();
 
    foreach (int column in columns)
    {
        // colGroups[column].Visible = false; // Object not found Error in binding
        colGroups[column].Filters.Clear();
        colGroups[column].Filters.Add(new Telerik.Reporting.Filter("=1", Telerik.Reporting.FilterOperator.Equal, "=0")); // Object not found Error in binding
    }
 
    return;
    */
 
    var tableBody = tableDef.Body;
    var tableCells = tableBody.Where(x => x.ReportItem != null).ToList();
    var zero = Telerik.Reporting.Drawing.Unit.Inch(0);
 
 
    foreach (int colIndex in columns.OrderByDescending(x => x))
    {
        tableBody.Columns[colIndex].Width = zero;
 
        // shrink all cell.reportItem(s)
        foreach (var cell in tableCells.Where(x => x.ColumnIndex == colIndex))
        {
            // cell.ReportItem.Visible = false; throws error during Binding
            cell.ReportItem.Width = zero;
                     
            if (cell.ReportItem is Telerik.Reporting.TextItemBase)
                ((Telerik.Reporting.TextItemBase)cell.ReportItem).CanGrow = false;
        }
    }
}
 
         
/// <summary>
/// ItemDataBound, Remove columns by settings its content Visibility
/// </summary>
/// <param name="table"></param>
/// <param name="columns"></param>
public static void RemoveColumns(this Telerik.Reporting.Processing.Table table, params int[] columns)
{
    RemoveColumns((Telerik.Reporting.Table)table.ItemDefinition, columns);
    var zero = Telerik.Reporting.Drawing.Unit.Inch(0);
 
             
    foreach (var textbox in table.TableCells(x => columns.Contains(x.ColumnIndex)).OfType<Telerik.Reporting.Processing.TextBox>())
    {
        // textbox.Visible = false; // Doesn't collapse column
        textbox.Width = zero;
        textbox.Value = string.Empty;
 
        TextboxCanGrowProperty.SetValue(textbox, false, null);
    }
 
    foreach (var column in table.Columns.Where(x => columns.Contains(x.Index)))
    {
        TableColumnWidthProperty.SetValue(column, 0D, null);
    }
 
}
 
 
private static IEnumerable<Telerik.Reporting.Processing.ITableCell> TableCells(this Telerik.Reporting.Processing.Table table, Func<Telerik.Reporting.Processing.ITableCell, bool> predicate = null)
{
    Telerik.Reporting.Processing.ITableCell cell;
    int colCount = table.Columns.Count;
    int rowCount = table.Rows.Count;
 
    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
    {
        for (int colIndex = 0; colIndex < colCount; colIndex = colIndex + cell.ColumnSpan)
        {
            cell = table.GetCell(rowIndex, colIndex);
 
            if (predicate == null || predicate(cell))
                yield return cell;
        }
    }
}
 
public static IEnumerable<Telerik.Reporting.TableGroup> Flatten(this IEnumerable<Telerik.Reporting.TableGroup> collection)
{
    foreach (var group in collection)
    {
        yield return group;
 
        foreach (var subGroup in Flatten(group.ChildGroups))
            yield return subGroup;
    }
}
 
private static PropertyInfo _tablecolumnWidthProperty = null;
public static PropertyInfo TableColumnWidthProperty
{
    get
    {
        if (_tablecolumnWidthProperty == null)
            _tablecolumnWidthProperty = typeof(Telerik.Reporting.Processing.TableColumn).GetProperty("Width", BindingFlags.Instance | BindingFlags.NonPublic);
 
        return _tablecolumnWidthProperty;
    }
}
 
private static PropertyInfo _textboxCanGrowProperty = null;
public static PropertyInfo TextboxCanGrowProperty
{
    get
    {
        if (_textboxCanGrowProperty == null)
            _textboxCanGrowProperty = typeof(Telerik.Reporting.Processing.TextItemBase).GetProperty("CanGrow", BindingFlags.Instance | BindingFlags.NonPublic);
 
        return _textboxCanGrowProperty;
    }
}


Thanks
Steve

2 Answers, 1 is accepted

Sort by
0
Accepted
Elian
Telerik team
answered on 26 Dec 2012, 03:08 PM
Hello Steve,

On ItemDataBound event, the processing item is already created and sized which means it is too late and changes made to the definition will have no effect. The easiest option would be to listen for the ItemDataBinding event and read the data-source manually, then change the table's definition accordingly. 
In order to change the width of the column, you have to change the following sizes:

  • The table itself 
  • The table's body column
  • All the items contained inside the corresponding column
 
The code should look like the following:
private void crosstab1_ItemDataBound(object sender, EventArgs e)
{
    //adjust the overall width
    this.table.Width = ...
    //adjust the body column width
    this.table.Body.Columns(2).Width =...
    //adjust all other columns that you want to change
 
    //adjust all the items in the corresponding column
    this.textBox10.Width = ...
    // ...
}

Kind 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
Steven
Top achievements
Rank 1
answered on 27 Dec 2012, 04:33 PM
Thanks, I finally got the solution to work.  
My main issue was that I was not accounting for the ColSpans.

I also had a SubReport within a Static Row which was re-sizing successfully, but I forgot to resize the SubReport's Report Width.

Here is my finished code.


/// <summary>
/// ItemDataBinding, Remove columns by settings its width to Zero
/// </summary>
/// <param name="tableDef"></param>
/// <param name="columns"></param>
public static void RemoveColumns(this Telerik.Reporting.Table tableDef, params int[] columns)
{
    var tableBody = tableDef.Body;
    var tableCells = tableBody.Where(x => x.ReportItem != null).ToList();
    var zero = Telerik.Reporting.Drawing.Unit.Zero;
 
    foreach (int colIndex in columns)
    {
        var column = tableBody.Columns[colIndex];
 
        // shrink all cell.reportItem(s)
        foreach (var cell in tableCells.Where(x => x.ColumnIndex == colIndex))
        {
            cell.ReportItem.Width = zero;<br>
            if (cell.ReportItem is Telerik.Reporting.TextItemBase)
                ((Telerik.Reporting.TextItemBase)cell.ReportItem).CanGrow = false; // value is still populated
        }
        // reduce width from ColSpans
        foreach (var cell in tableCells.Where(x => x.ColumnIndex < colIndex && x.ColumnIndex + x.ColumnSpan >= colIndex))
        {
            cell.ReportItem.Width = cell.ReportItem.Width.Subtract(column.Width);
        }
        // reduce width from Table and Column
        tableDef.Width = tableDef.Width.Subtract(column.Width);
        column.Width = zero;                
    }
}



Thanks for the help
Tags
General Discussions
Asked by
Steven
Top achievements
Rank 1
Answers by
Elian
Telerik team
Steven
Top achievements
Rank 1
Share this question
or