Can't set the table width in WPF through - wpf

I am making WPF application.I have a data grid and all columns have set their width to "Auto".When i start scrolling through the table some of the columns start expanding.My question is: Can I set the column width to fit the longest data in column at the beginning (without expanding columns when i scroll)?

the column width for wpf expanding when the shown data need more space when it set to Auto then this work will be done automatically.

Well this is due to the virtualization of the DataGrid. Only the items, which are visible are rendered and the controls are reused in case of scrolling (if you are activating it). And so the width will not be correct, since the longest element is not rendered yet. A list control performs very well, although you might bind many items to it.
I think you have 2 options
Turning off the virtualization, which might be a proper solution, if you don't have many items to show. I've to admit, I didn't try it, so no warranty. You can turn it off via <DataGrid VirtualizingStackPanel.IsVirtualizing="False"/>. For more information on the VirtualizationStackPanel pls have a look here.
Another solution may be TextTrimming. TextBlocks can show Ellipses if the text is too long. Therefor you will have to assign a custom datatemplate to the column put the following as content e.g. <TextBlock Text="{Binding}" TextTrimming="WordEllipsis"/>. Please note, that you will also have to provide a customer CellEditingTemplate, if the user shall be able to edit the values. For more information about TextTrimming please have a look here. To get an idea how the whole DataTemplate thing regarding DataGrids will work, you can have a look here.

Related

Which Table/Grid Control in WPF?

I am looking to display tabular data (tv channels), but with options such as DataGrid/UniformGrid/Table with FlowDocument/etc. I cannot figure out what would be the best option. The main issues is that the cells aren't uniform in size as it varies based on length of time, and I would like to put padding between them as well. Additionally, I need to only be able to display a portion of the table, and allow them to scroll Up/Down/Right to view the rest.
What would be the best WPF Control Option for this? Here is a small illustration of what I am going for. The white square in the upper left is what I would want to display at start, and allow them to scroll to the rest of it.
There are several ways to accomplish what you're trying to do here. If performance is not an issue then I would ignore virtualization and try the DockPanel The drawback here is that you would have to add the items in order rather than adding them by row.
Another option would be to use two stack panels (one in each direction). This addresses the adding issue, but requires the use of more panels.
Both of the previous two options would require individual items to have their height/width set.
A final option (depending on how large your grid is), would be to use a Grid with fixed sized rows and columns with items that span rows (using the rowspan property). The drawback of this method is that I don't know of any good way to create this control in xaml for unspecified numbers of rows/columns so you would have to create it in code to get the needed number of rows/columns.
If you have performance issues you could try using the VirtualizingStackPanel. If this still doesn't meet your performance requirements then you will need to subclass the VirtualizingPanel and tailor it to meet your specific needs.
See here for more information on Panel performance.
I suggest trying the two StackPanel method first, then the VirtualizingStackPanel method and finally, if that doesn't work, then try the VirtualizingPanel
Padding is easily accomplished by setting the Margin property on each subcontrol.
For scrolling use the ScrollViewer

writing a grid that has both column and row virtualization

I need to write an excel-like grid that can have a lot of cells (400x400). All columns have the same width and all rows the same height. Each cell can contain text or be empty and each cell can have a column and/or row span. I suppose this will never work with the Grid panel and I suppose I will need UI virtualization in both column and row direction.
So my first try was to create a virtualizing grid by deriving from VirtualizingPanel and implement IScrollInfo. This could have "easily" be the solution except that I ran into a problem:
To provide IScrollInfo with the relevant information about scroll size and position and to be able to detemine wich items need to be created (realized) next using the ItemsContainerGenerator, I need to know the column index, row indeox and columnspan for each child item (cell). The only way I can think of to do this is using attach properties. The problem is: I can only read the values of attached properties if the ItemContainer that has them is already realized. So I am in a catch 22 here. To know what to realize I need to realize all items. To provide the data for IScrollInfo I need to realize all items.
So it seems that I am at a dead end with this approach.
Do you have any idea how I could implement a control like this or know how I could reslove the above problem?
It strikes me that you may not need to instanciate the UI elements themselves- you can very easily have a collection of DependencyObject-derived viewmodels, each of which has the WidthProperty and HeightProperty set (and possibly bound to the equivalent Width and Height properties of the visible cell UI element, once those are created).
Storing 160,000 (400x400) class instances shouldn't be a problem, especially if you are able to index into the set using row and column.

WPF Datagrid column resizing upon changing FontSize

I am having an unexpected issue with DataGrid resizing.
Here is the situation: one of my application requirements is that users can change all my DataGrid's FontSize on-the-go. The grid should therefore be updated accordingly.
My columns are all defined to Auto-resize. The problem is: when I increase the FontSize, the DataGrids are correctly resized.
However, when I decrease FontSize, all rows resize appropriately, but the column headers just keep their current size!
I'd say that the auto-resizing method is strange in this case, I mean, why shouldn't it juste resize the column like it did with the rows?
FYI, I'm working under .NET 3.5 & WPFToolkit's DataGrid.
Hmmm... I haven't dealt with the specific issue you're having. But there was a similar problem I ran into and the corresponding solution I came up with.
The DataGrid is great at increasing its column sizes when needed... but struggles with decreasing them. I'm surprised that the rows shrink correctly for you... (I'm guessing something with the font size changing causes a re-calculation). But I'm guessing to get the column-headers you're going to have to manually force an layout refresh as suggested in the link provided above.
Hopefully, the approach above will also work for your specific problem. Or at least maybe you find something useful from that.

WPF DataGrid populating the cells as they become visible

I have always been using a Syncfusion virtual grid which works on the basis of an override on that grid that is fired for each cell that is visible! It provides me with information on the row and column and some cell object that lets me set the value of that cell, its formatting, colours etc.
This allowed for very fast scrolling on very large datasets, since I simply have to 'read out' the value like dataSet.Tables[0].Rows[1000000]["LastName"].ToString()
Is there anything similar exposed by the WPF DataGrid?
EDIT
I need to make myself clearer - I know about virtualization and that it switches itself off when you do grouping etc. Having run a test with grouping enabled over a dataset of 20,000
rows made my grid choke on itself.
Therefore my previous question stands on its own!
Is there any way the grid allows me to fill in the text and do some formatting through some override or callback?
Thanks
The DataGrid uses virtualization by default. This works by either creating and deleting cells on the fly or by recycling the visible cells and repopulating them with the current row's data. This can be turned off as well as tweaked by playing with the 'VirtualizingStackPanel.VirtualizationMode' property and is forced off in many situations (grouping is a good example). This virtualization can be a godsend and a curse. If you have a simple set of requirements, then it makes it dead easy to get good performance. If on the other hand you are doing complex runtime binding, including triggers and custom columns, then it becomes a bit of a nightmare.
a couple of important reads:
http://msdn.microsoft.com/en-us/library/cc716879.aspx
http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.aspx

WPF DataGrid is extremly slow, how can I improve the Initial Loading time?

I have a Window with a DataGrid showing grouped Data.
I am loading around 4 x 300 items in the WPF DataGrid which are grouped in 4 groups.
Grouping disables Virtualization.
I set IsAsync="True" so my Window opens fast but the DataGrid is just filled AFTER 11 SECONDS ???
What can I do to speed up the loading/display of my data?
You stated it yourself - grouping disables virtualization; I think for now showing each group separately (in its own datagrid) is the way to go if at all possible... or some other similar trick to simply not show all the items using grouping.
Much later edit:
There's actually quite an interesting write-up at http://jerryclin.wordpress.com/2008/02/22/listbox-grouping-and-virtualization/ on how to go about doing things if you REALLY need ListBox grouping with virtualization. Not sure it's worth the pain, but it's possible.
Not sure if its related, but I had a similar problem with the DataGrid in which it took literally seconds to refresh after a window resize, column sort, etc. and locked up the window UI while it was doing so (1000 rows, 5 columns).
It came down to an issue (bug?) with the WPF sizing calculations. I had it in a grid with the RowDefinition Height="Auto" which was causing the rendering system to try and recalculate the size of the DataGrid at runtime by measuring the size of each and every column and row, presumably by filling the whole grid (as I understand it). It is supposed to handle this intelligently somehow but in this case it was not.
A quick check to see if this is a related problem is to set the Height and Width properties of the DataGrid to a fixed size for the duration of the test, and try running again. If your performance is restored, a permanent fix may be among these options:
Change the sizes of the containing elements to be relative (*) or
fixed values
Set MaxHeight and MaxWidth of the DataGrid to a fixed value larger
than it could get in normal use
Try another container type with different resizing strategy (Grid, DockPanel, etc)
In .NET 4.5.2 virtualizing grouped items is finally possible:
<DataGrid VirtualizingPanel.IsVirtualizingWhenGrouping="True" />
https://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingpanel.isvirtualizingwhengrouping%28v=vs.110%29.aspx

Resources