I have a Hierarchical Datagrid from version 12.1.
I load a collection of class Employee in de Datasource. Each Employee has a property Tasks which is a collection of class Task.The property Tasks however is always initially empty (so the grid is 1 level deep).
In my app the enduser can assign a Task to an Employee. The Task row needs to be shown beneath the Employee row, this all works fine. But I also need to autosize all the columns of all the rows. And I want to size everything so that all the data in the cells are visible to the enduser.
I try to do this in the InitializeLayout eventhandler, as follows:
private void ultraGrid_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { Infragistics.Win.UltraWinGrid.UltraGrid grid = (Infragistics.Win.UltraWinGrid.UltraGrid)sender; grid.DisplayLayout.Override.AllowUpdate = Infragistics.Win.DefaultableBoolean.False; grid.DisplayLayout.Override.CellClickAction = Infragistics.Win.UltraWinGrid.CellClickAction.RowSelect; grid.DisplayLayout.Override.SelectTypeRow = Infragistics.Win.UltraWinGrid.SelectType.Single; Infragistics.Win.UltraWinGrid.UltraGridLayout layout = e.Layout; Infragistics.Win.UltraWinGrid.UltraGridOverride ov = layout.Override; ov.AllowColSizing = Infragistics.Win.UltraWinGrid.AllowColSizing.Free; layout.Bands[0].Override.RowSpacingAfter = 2; layout.Bands[0].Override.RowSpacingBefore = 3; foreach (var band in layout.Bands) { band.PerformAutoResizeColumns(false, Infragistics.Win.UltraWinGrid.PerformAutoSizeType.AllRowsInBand); foreach (var col in band.Columns) { col.PerformAutoResize(Infragistics.Win.UltraWinGrid.PerformAutoSizeType.AllRowsInBand, true); } } }
The PerformAutoResize in the foreach loop is not giving me the result I expected. The added Tasks at level 2 in the grid are not resized at all so it seems. Can you please help me Infragistics? I need your expert advice on this one.
Hi
PerformAutoResize is a method that resizes the columns at the time you call it. The columns are not continuously resized all the time. So if you add a new row to the grid, you need to call PerformAutoResize again on the columns of that band in order to make it resize.
Also, the columns in each band of the grid are synchronized by default. So column 0 in band 0 will always have the same width as column 0 in band 1. You probably want to turn this off so you can size the columns in each band independently. You do that by setting the ColSizing property on the Override to one of the 'Free' settings.
Hi Mike,
First off, thanks for answering.
1) What I do after a task is added to an Employee is:
1: this.ultraGrid1.DataSource = Employees; 2: this.ultraGrid1.Rows.Refresh(Infragistics.Win.UltraWinGrid.RefreshRow.ReloadData, true); 3: this.ultraGrid1.Rows.ExpandAll(true); 4: this.ultraGrid1.ActiveRow = this.ultraGridPrescribed.Rows.First();
InitializeLayout eventhandler is called after codeline 1 and 4. There (in the InitializeLayout event handler) I go in the foreach loop through each band and column to call PerformAutoResize like you can see in the code sample from my 1st post. So... What am I doing wrong according to you? I don't understand.
2) I couldn't find the ColSizing property, but I did find the AllowColSizing property in the Override property of the Band. So I set AllowColSizing property to Free on the bands Employees and Tasks. And I also set ColumnAutoSizeMode to AllRowsInBand at both bands. Didn't work.
3) Is it perhaps a problem that the Employees band uses Row Layout for the column arrangement and Tasks band uses Groups and Levels?
Hey Mike,
Sorry, busy busy busy...
Finally got around to making a small sample project (see attached ZIP file)
1) start up project.
- Notice that the info in both grids are sized properly
- As an extra problem, also notice that a + sign is displayed in front of the employees in the right grid while not actually having tasks in the collection. But this is a different problem. I worked around this in the real application by expanding and collasping all.
2) Select 'Task 1 blablabla..." in the left grid. Select an employee (for example "Peter") in the right grid.
3) Click on "Add Task"
- Notice how the added task is not resized at all.
Why?
Hi,
DannyvdK said:As an extra problem, also notice that a + sign is displayed in front of the employees in the right grid while not actually having tasks in the collection. But this is a different problem. I worked around this in the real application by expanding and collasping all.
That sounds like a very inefficient solution. All you have to do to fix this is set:
ultraGrid2.DisplayLayout.Override.ExpansionIndicator = Infragistics.Win.UltraWinGrid.ShowExpansionIndicator.CheckOnDisplay;
DannyvdK said: 3) Click on "Add Task" - Notice how the added task is not resized at all.
Unless I a missing something, there's no real mystery here. This is exactly what I explained above - PerformAutoResize is a method, not a property. The grid doesn't continuously resize every new or modified row and keep them autosized. And there is nothing in your code that is telling the grid to auto-size the cells in this new row.
The only place you are calling PerformAutoResize is in the InitializeLayout event and that doesn't get called with you add a new task because you have no done anything that would require re-initializing the Layout.
You are setting the DataSource on each grid and also refreshing the rows, but this is essentially a no-op in this sample, because you are setting the DataSource to the same value it's already set to.
It has nothing to do with your issue, but re-setting the DataSource is not a good practice, anyway. This is going to cause you to lose the column width, positions, selection, and any other user-customizations made to the grid.
Anyway, if you want to autosize when you add a task, why not just call the PerformAutoResize method at the end of the add task method?
As for the ExpansionIndicator. Thanks. Didn't know about that property. Works.
As for the PerformAutoResize problem. I know it's a method and not a property. My InitializeLayout in my real application is called each time I add or remove stuff. I don't know why exactly. So there must be a difference with my sample project. Need to find that difference. Didn't test it in the sample project. But indeed in the sample project my initialize layout is only called once. Like you said.
But calling PerformAutoResize after adding a task is an option for me in the real application also, so I' ll do that. So to test it I've added a PerformAutoResizeColumns at the very end of the routine add task routine in the sample project. So now the routine looks like:
private void buttonAddTask_Click(object sender, EventArgs e) { Task tsk = (Task)ultraGrid1.ActiveRow.ListObject; Employee emp = (Employee)ultraGrid2.ActiveRow.ListObject; if (emp.Tasks == null) { emp.Tasks = new BindingList<Task>(); } emp.Tasks.Add(tsk); ultraGrid1.DataSource = DummyRepository.Tasks; ultraGrid1.Rows.Refresh(Infragistics.Win.UltraWinGrid.RefreshRow.ReloadData, true); ultraGrid2.DataSource = DummyRepository.Employees; ultraGrid2.Rows.Refresh(Infragistics.Win.UltraWinGrid.RefreshRow.ReloadData, true); ultraGrid2.Rows.ExpandAll(true); ultraGrid2.DisplayLayout.PerformAutoResizeColumns(false, Infragistics.Win.UltraWinGrid.PerformAutoSizeType.VisibleRows); }
Please adjust the sample project accordingly. Notice the 1st time you add a task, the columns of the added task don't get resized. The 2nd task you add does. So we' re a little bit further, but how come this happens?
Last, but not least. I don't want to necessarily reset the DataSource, but I'm struggling to get the grids to do exactly what I want. This is what I've come up with so far. So if you can help me, please do. Adjust my sample project the way you think it should work. I could use a little help...
DannyvdK said:My InitializeLayout in my real application is called each time I add or remove stuff.
Maybe in your real application, you are setting the grid's DataSource to a new object, instead of the same one, so this is causing InitializeLayout to fire. If that's the case and you are changing our DataSource and returning a new object, then I'm not sure how I can help you there. You would have to stop doing that and simply modify the same data source object like you are doing in this sample project.
DannyvdK said:ultraGrid2.DisplayLayout.PerformAutoResizeColumns(false, Infragistics.Win.UltraWinGrid.PerformAutoSizeType.VisibleRows);
The problem here is that you are specifying VisibleRows. You just added the new row to the data source, but this is inside an atomic block of code. So the new row you just added is not yet visible in the grid. The second time you call this code, the first row you added already exists, so that's why it works the second time. Change it to AllRowsInBand, and it works fine:
ultraGrid2.DisplayLayout.PerformAutoResizeColumns(false, Infragistics.Win.UltraWinGrid.PerformAutoSizeType.AllRowsInBand);
DannyvdK said:Last, but not least. I don't want to necessarily reset the DataSource, but I'm struggling to get the grids to do exactly what I want. This is what I've come up with so far. So if you can help me, please do. Adjust my sample project the way you think it should work. I could use a little help...
If you are using the same data source object (like this in sample) and it still doesn't work - the grid does not show the newly-added row, which is what happens in your sample, then I think that's because of the way your data source is working. Your data source in the sample has two BindingList<T> properties. Inside of AddTask, you are not adding a Task to the existing list of Tasks. Instead, you are setting the List to an entirely new list. the DataBinding functionality in DotNet is not going to be able to handle that. To make this work, you would have to change a number of thing.
First, you can't use Automatic Properties for the Tasks and Employees lists. This won't work because these collections will initially return null at the time you bind the grid and thus the grid and the BindingManager will be unable to determine the data structure of the child rows. Instead, these properties need to always return the same instance of a list, and they must never return null.
So your Employee object needs to be modified:
//public BindingList<Task> Tasks { get; set; } public BindingList<Task> tasks; public BindingList<Task> Tasks { get { if (null == this.tasks) this.tasks = new BindingList<Task>(); return this.tasks; } }
Notice I also remove the setter for the Tasks collection, because setting the collection will not work right with DataBinding.
You probably need to do the same thing to the BindingLists on your DummyRepository, too.
private static BindingList<Task> tasks; private static BindingList<Employee> employees; internal static BindingList<Employee> Employees { get { if (null == DummyRepository.employees) DummyRepository.employees = new BindingList<Employee>(); return DummyRepository.employees; } set { if (DummyRepository.employees == value) return; DummyRepository.employees = value; } } internal static BindingList<Task> Tasks { get { if (null == DummyRepository.tasks) DummyRepository.tasks = new BindingList<Task>(); return DummyRepository.tasks; } set { if (DummyRepository.tasks == value) return; DummyRepository.tasks = value; } }
This actually makes your AddTask method a whole lot simpler:
private void buttonAddTask_Click(object sender, EventArgs e) { Task tsk = (Task)ultraGrid1.ActiveRow.ListObject; Employee emp = (Employee)ultraGrid2.ActiveRow.ListObject; //if (emp.Tasks == null) { // emp.Tasks = new BindingList<Task>(); //} emp.Tasks.Add(tsk); //ultraGrid1.DataSource = DummyRepository.Tasks; //ultraGrid1.Rows.Refresh(Infragistics.Win.UltraWinGrid.RefreshRow.ReloadData, true); //ultraGrid2.DataSource = DummyRepository.Employees; //ultraGrid2.Rows.Refresh(Infragistics.Win.UltraWinGrid.RefreshRow.ReloadData, true); ultraGrid2.Rows.ExpandAll(true); ultraGrid2.DisplayLayout.PerformAutoResizeColumns(false, Infragistics.Win.UltraWinGrid.PerformAutoSizeType.AllRowsInBand); }
Mike,
I am trying to export grid in PDF but the column content is not displaying correctly it's cutting a little bit.
Please see my code and attached screenshot.
Private Sub ugrdExporter_ExportStarted(sender As Object, e As Infragistics.Win.UltraWinGrid.DocumentExport.ExportStartedEventArgs) Handles ugrdExporter.ExportStarted
Try
ugrdExporter.AutoSize = Infragistics.Win.UltraWinGrid.DocumentExport.AutoSize.SizeColumnsToContent
Catch ex As Exception
End Try
End Sub
Private Sub ugrdExporter_InitializeRow(sender As Object, e As Infragistics.Win.UltraWinGrid.DocumentExport.DocumentExportInitializeRowEventArgs) Handles ugrdExporter.InitializeRow
On one of post it mentined like this :The best thing to do is to leave on the AutoSize property or auto-size the columns in the export layout to ensure that the data will fit in the report.
So how to do autosize column ? is it same like this ?
I am using 13.1.20131.2060 version.
I'm not sure if BeginExport is any better. That event is obsolete, so you might try ExportStarting, but event that might be too late. The best thing to do is to set the property before you call the Export method. I typically set it at design-time.
If that still doesn't work, then my best guess is that there is something about your data or your grid settings which is causing the autosizing to fail. What version of the controls are you using?
If you can post a small sample project demonstrating the problem, we would be happy to check it out.
Thanks for quick reply, So now I am doing like this still it's not working.
Private Sub ugrdExporter_BeginExport(sender As Object, e As Infragistics.Win.UltraWinGrid.DocumentExport.BeginExportEventArgs) Handles ugrdExporter.BeginExport
ugrdExporter.AutoSize = Infragistics.Win.UltraWinGrid.DocumentExport.AutoSize.SizeColumnsAndRowsToContent
The AutoSize property on the exporter needs to be set before the export operation begins. You can't set it in these events - it's too late by then.