WPF Grid of Images - Best control to use? - wpf

I'm trying to convert my VB project to WPF, and one big problem I'm having is what to do about a large GridView that contains in each cell a single image. The grid needs to be very large so is the best way to do this in WPF a datagrid, or a dynamically generated Grid control, or something else? I'm not sure which controls give the best performance as the grid could be 100 x 100 or more.
Any suggestions would be brilliant :o)

I would try using the WrapPanel, to allow for items to flow nicely.
If the images are not of the same size though, you could try the UniformGrid within a ScrollViewer, as it will align items for you uniformly.
Performance wise, I'd say don't optimize prematurely! When you have a nice User Experience, you need to do some reading and decide for yourself. Have a look here.

Related

Fixed Document Tables?

I am looking for a layout control or other means of laying out data in a tabular format on a Fixed Document for reporting. I have used MigraDoc quite extensively in non WPF projects and its table object allows for a granular layout for each piece of data to be displayed in the table. Borders can be turned off on the cell level, columns can be merged/spanned, etc. Are there any controls that offer this kind on control within WPF? I have not seen where the DataGrid or the Grid will do what I need... easily. My data is not bound as I need to have full control over how it is displayed. I am not using a flow document so I cannot use the table object that it offers. Anyone have any suggestions? For now, I have resorted to programmatically creating a Grid and then inserting a Border containing a TextBlock within each cell. There just has to be a cleaner way!
BTW - I am looking to use native WPF controls in this project which is the reason that I am not using MigraDoc.

Multiline WPF textblock: different alignment for lines

Is that possible to set different horizontal alignment for different lines of multiline textblock?
For example, I want to center header of my text, but main text I want to align by left side. I'd not want to use several textblocks for this issue.
Thanks.
I do not think you can get what you are looking for using the TextBlock control, this because the Inline elements that you can add in your TextBlock does not allow you to control the horizontal alignment (line by line).
Anyway I do not think that this is the best approach, in fact, as specified by MSDN:
TextBlock is not optimized for scenarios that need to display more than a few lines of content; for such scenarios, a FlowDocument coupled with an appropriate viewing control is a better choice than TextBlock, in terms of performance. After TextBlock, FlowDocumentScrollViewer is the next lightest-weight control for displaying flow content, and simply provides a scrolling content area with minimal UI. FlowDocumentPageViewer is optimized around "page-at-a-time" viewing mode for flow content. Finally, FlowDocumentReader supports the richest set functionality for viewing flow content, but is correspondingly heavier-weight.
So if you want to have more flexible control, and also better in terms of performance for what you ask it to do, you should use the FlowDocument.
I want to add a final remark. If you're looking for a dramatic improvement in performance, and you think that a single TextBlock is the right solution, I suggest to use Visual elements and the relative DrawText method instead. But if you're looking for an easy control to maintain in the future the choice is FlowDocument, as already said.

WPF: Why all the love for the Grid control?

Seen various examples of WPF applications I've seen the use of the Grid control for almost anything, even simplest things with only 1 column or row.
Also, the WPF templates start with an empty grid.
For me, using StackPanel or DockPanel is less verbose and are better for maintenance (think adding a row later and having to add +1 to all the other rows)
Why is Grid better or what I am missing?
Two words: Star sizing. The Grid makes it possible to size content to the space that contains it without explicitly providing a size for the container. The panel controls don't.
I think part of the reason for Grid being the default element is that it's (slightly) more designer-friendly.
With a Grid, there is no restriction on having multiple elements within a single Grid "cell", which allows a designer with free placement to have the same flexibility as a Canvas, but still have the automatic layout capabilities that Grid (and the other nicer layout controls like StackPanel and DockPanel) contains.
not missing anything. I have quite a lot of grids in my application(s), but not necessarily as top level element and definitely not to the extend you describe.
Could be many people just dont realize that they can remove the initial grid, and instead they put their own control into the grid.
I have found that for more elaborate windows, it is easier to break it down into functional areas that are fairly independent (movement and size wise) of the others. Grids allow those areas to coexist in a single panel, and allow them to be positioned without regard for where other controls are (to some extent).
For instance in a project I am working on right now, I have a window that is going to be a shipping manager. I want three list views (Shipments, Packages, Items) I have a grid control with two columns; one with the Packages list and a grid splitter, the other with a nested grid with the other two lists and a grid splitter.
i have seen many designers break their window down into areas like this, and doing it with anything other than a grid just doesn't work since there are no discreet "cells" that items indirectly live in. Quite a few program windows take this design and so I guess when they had a meeting and asked what should be the default container panel, grid was the choice based on that fact.
Cory

WPF column resize performance issues

Are there in general any known performance issues in WPF related to grid column resizing?
I have an application where I need to do some particular things in a column, but for all the different solutions I find the column resizing gets slow. This applies when I have typically more than 1000 elements in my list, but I assume this isn't too much for WPF..? So; the general question is whether you've experienced slow column resizing, and whether you've found solutions for this? What was causing it?
Some more details about my particular case:
I can have two different things in my columns; ComboBox or TextBlock. The ComboBox should fill the whole column and follow on column resize, and clicking an empty area of a column with a TextBlock should select the row. This is where the problem is. For all solutions I have to this the column resizing gets slow. The only way to make resizing smooth that I've found is by adding a StackPanel outside them with Orientation="Horizontal", but with this I'm unable to achieve the styles described above.
Here are some observations:
Adding style HorizontalContentAlignment="Stretch" to the items of the list makes the ComboBoxes stretch and the TextBlocks clickable, but also column resize slow.
Adding Background="Transparent" to either the StackPanel or the elements that are inserted inside them solves the problem too, but makes resizing slow.
Adding an outer StackPanel with property Orientation="Horizontal" makes resizing smooth, but I'm unable to apply the styles as described.
Have you tried virtualizing the elements in the ListView? When you are virtualizing, the virtualizing panel only creates the visuals for the elements that are in the view. This allows you to have large numbers of items without performance issues like you mention. See VirtualizingStackPanel for more details. Also The Layout System. You can create your own virtualizing panels. If you look up "virtualizing+wpf" on google you'll find lots of hits for virtualizing Canvases, WrapPanels, and etc.
I hope this helps.

How can I prevent the VS WPF designer putting margins on every object from the toolbox

When I drag a control from the toolbox on to the Visual Studio 2008 WPF design surface, it sets a margin based on where I dropped it and a default size.
Is there any way to prevent VS setting those? When I drop a control on a stackpanel I want it to flow in to the existing controls in the panel.
Thanks!
I've never found a way to prevent this. I just type the XAML instead.
EDIT:
I wrote the above nearly three years ago. In the meantime, it would appear that the design-time experience has gotten a lot better.
While the designer still adds hard-coded margins if you drag-and-drop, there are ways to remove those margins without having to do it by hand.
Here's a link to an article that illustrates how to use design tools in Visual Studio 2010 to lay out a form without having to type any XAML. (Despite the title, it's about WPF.)
The first part of the article shows hard-coded pixels, but I've linked to the second part that shows how to lay out the controls without that hard coding.
Layout Techniques for Windows Form Developers
When I drop a control into a stackpanel, it doesn't add margins, it "flows" in with the rest.
The controls you drop onto the design surface have a margin by default because that's how it knows where it's placed. What I typically do is create a grid and set it's margin where I want it, then create columns and rows to put controls into. I drop in my other controls which will add margins which are usually not what I want. After I have all my controls into my grid, reasonably placed, I switch to XAML view and either remove the margin completely (which causes a control like a button to fill the entire space), or make the margin something like 5, which puts some nice padding around the control.
Bottom line...and this is especially true with Silverlight development, you must get used to manipulating the XAML directly. It's the only way you'll get the layout exactly where you want it. This is my opinion and most everybody in my shop who does WPF/silverlight development.
Unfortunately there does not appear to be a means to do this.
The default size is set as a result of you manipulating the size of your control is the designer. When you increase the width and/or height of a control the designer is interpreting your actions as a request to make the control that specified width and/or height.
A similar situation is encountered with the margins. As you alter the position of your control within the designer, it modifies properties to achieve the layout you've created. In the case of most containers the simplest solution is to modify margins in order to achieve the desired position, as you've already pointed out the simples solution is not always the most desired.
Personally I prefer to only use the XAML editor and only occasionally take a peak at the WPF Designer when I want to see the current layout. I also tend to favor using the Grid to layout most of my windows/controls as it provides the greatest flexibility not only for sizing and positioning, but for other tasks/features such as animations, transforms, etc.

Resources