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
Related
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.
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
When building WPF forms that are used for data entry (e.g. A bunch of labels next to a bunch of textboxes and comboboxes) I've seen two methods:
Create a master Grid, divide it into two columns, and add rows with Height="auto" for each field and two rows for header and footer (and submit button), and each label and text box has their own row.
The other method is to create a master stackpanel and inside it a horizontal stackpanel for each pair of label-textbox.
How do you design your data entry forms? I'm currently torn between the two methods, maybe there's an alternative that I'm unaware of?
EDIT: Henk said I should define best and I think I agree, by best I mean easiest to maintain, create, align and add or remove fields from as demands change.
So far the only criteria by which the grid is better is ease of alignment.
definately first method!
it's well aligned, especially with the use of SharedSizeGroup so you can have the same alignment eg in different Groupboxes.
I have used both and it really depends upon how your form is going to look. If you have a really simple layout where you are going to have labels and and corresponding fields of approximately the same size then your first method works well. It lets you create two columns that line up very well. However, if your fields are of varying withs, and heights and you want to be more complex with the layouts then a hybrid approach may be best. If you are doing anything more complex than just labeling fields on basic controls you may want to create user controls rather than just using what is there out of the box. When laying out fields in both a horizontal and vertical jagged manner it becomes hard to maintain the grid layout as you have to wind up having a grid with lots of columns and rows. The fields and labels have to span columns and rows to get your alignment correct. This works, but is a nightmare if you ever want to reorganize the form.
For what you wrote, it sounds like the first approach is best. If its simple now and some point in the future it becomes more complex, its easy to change. However, if you have a more complex layout already then a pure grid based approach probably isn't best.
Disclaimer: I am going to say little about my own company's product in my blog that gives comparison and challenges in maintaining forms.
Both Grid and StackPanel have Maintanence nightmares so we went on different approach of creating Form Layout, and I have outlined our approach here on this link,
http://akashkava.com/blog/296/advanced-data-form-with-ui-atoms-on-wpf-and-silverlight/
I am new to WPF environment and I am experiencing some problems like if there are alots of things how do we manage them.for example I have three borders each of same size same location and they contains controls like textboxes etc etc we construct them sequentially but when it comes to edit we get in trouble modifying the border that is at bottom.
So in short how do we manage many controls on single page so that it remains easy to edit
Not sure I completely understand your concerns, but here are several point that make editing WPF UI pretty easy:
Correct usage of layout panels. If you will use approach with absolute positions for each control then it might become a nightmare to move or resize some of your controls. Correct layout (and panels such as DockPanel/StackPanel/etc) might help you a lot.
Incapsulating repeatable parts. WPF has a lot of feature to avoid repeating UI code. I'm talking mostly about Styles and Control templates at the moment. If you have your borders repeating through the entire window, maybe you should think on extracting this border as a ControlTemplate for ContentControl for example?
but I've found that encapsulating controls such as borders, textboxes etc in User Controls helps to keep things well managed (not to mention helps reduce code), similarly using a Resource Dictionary to store styles/animations is useful for very big projects (remember though that the local resources will take precedence when applied so remove them if they not in use)
furthermore, using Layout Panels such as Stacks,Grids and Dockpanels allows you to collapse User Controls when not needed or otherwise (also I've found that for some reason, Grids allow controls to overlap (when items are not correctly ordered in Grid Rows and Columns) which can lead to some elements not being seen in design.
Plan your layout properly and think through which Panels would be best for them, having to go back much later and change can be annoying (though admittedly it happens).
Also remember to use partial classes to properly structure your stuff, having to read through 1000+ lines of code to find something can be a nightmare.
I'm looking for way to present equally sized elements in a fixed number of rows and any number of columns. (Think of iTunes' or Picasa's album view. I believe some platforms refer to this as a 'gridview')
A WrapPanel would do the job, but I'm binding against a very large collection of objects, so I need virtualization.
I've been looking around the web, and found both commercially available VirtualizationWrapPanels and blog posts on how to implement your own VirtualizationPanel, but I can't seem to find any simpler solutions.
Is it possible to arrange virtualized databound items in a grid-style view (fixed number of rows) with standard WPF components?
I've recently had to have a hunt round for similar functionality and struggled to find anything that was production ready.
I found a series of articles and sample code that contain a Virtualizing Tile Panel.
I've been using it and it has been fairly stable. There were some changes that needed to be made though. We had to add some of the keyboard control into the panel as it wasn't implemented, tabbing needed to be changed as well as adjusting tile sizes, etc. It's a good starting point if you decide to roll your own.
One major caveat though was that it also MUST have a parent that is constrained to a limited size else it errors out. This is not normally an issue as you will want it to be limited in size so you can enable scrolling. There may be a solution to this particular problem but we didn't have time to investigate.
A quick-and-dirty solution is to use a list (in your case a horizontal one) of "grouping items" (in your case vertical ones) which will determine desired number of rows. Virtualization will occur on the "groupers".
It is the responsibility of the Panel to provide Virtualization. Unfortunately the framework only provides a virtualizing StackPanel:
http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingpanel.aspx
There is a very good blog post that provides a virtualizing WrapPanel here:
https://blogs.claritycon.com/custom-panels-in-silverlight-wpf-part-4-virtualization-7f3bded02587
Another alternative is to use a DataGrid, this will virtualize for you.