Silverlight 4 nested ListBox controls performance issue - silverlight

I am working on a silverlight page that will have a horizontal list box that will contain a list of "cards". Each "card" contains a vertical list box with some text in it. However, I am running into a lot of performance issues. Has anyone experienced any performance issues with nested listboxes in the past?

If its a DataGrid then Paging can give good performance. If its ListBox then we should keep an eye on the count of data binded with listbox.
Are you trying to bind the full list on single shot from server ? Then this will definitely affect the performance.

UI Virtualization might help you. Try to use VirtualizingStackPanel (instead of StackPanel) as the ItemsPanel of your Listbox:
<ListBox>
...
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

Related

Silverlight set ListBoxDragDropTarget children/items from code behind

I have an app which builds up list boxes programmatically from the code behind.
I would like to make the elements contained in the list boxes draggable.
I know this can be achieved in the xaml by the use of a ListBoxDragDropTarget by using the following xaml code :
<toolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True">
<ListBox Width="200" Height="500" x:Name="FromBox" DisplayMemberPath="FullName">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</toolkit:ListBoxDragDropTarget>
However i need to achieve this from the code behind rather than through xaml. Is there a way of setting the drag drop target from the code behind?
I cant seem to find a property which will allow the dragDropTarget to be set. Something like:
Dim target As New ListBoxDragDropTarget
target.children.add(listbox) / target.items
Not sure if it's possible.
Thanks in advance!
Sorted the problem in the end.
I ended up setting the ListBoxDragDropTarget.content to the list box. (Which contained multiple objects)
target.Content = listBox
I then added the target to the wrapPanel, then finally added the wrapPanel to my main grid.
wp.Children.Add(target)
grdApps.Children.Add(wp)
The drag / drop functionality is now working!

WPF GridView: "Newspaper" Column?

I'm not sure how else to describe this, outside of calling it a "newspaper" column.
Essentially I have a potentially long list of codes that I want to display in a grid, and I have limited vertical real estate. I would like to show these codes (which are all from the same database column) in multiple columns, maybe 3-5 columns across.
I can absolutely break the data up into separate sources and bind to them separately if that is the best solution, but I thought there might be an easy, built-in way to accomplish this with WPF.
This is actually trivial using a WrapPanel.
For a hard-coded list:
<WrapPanel Orientation="Vertical">
<ItemOne />
<ItemTwo />
...
</WrapPanel>
For a data-bound list:
<ItemsControl ItemsSource="...">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="...">
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If desired you can replace the ItemsControl with a ListBox or make it a ComboBox or whatever. You can use a default template for your data or use a custom template as shown above. You can even use a ListView along with a GridView if you want a multi-column list.
I suspect what you're looking at here is a custom layout panel which has a well defined height and then wraps into the next column. You could then use the ItemsPanelTemplate of the list control to use your new custom panel.
With respect to the development of the panel itself, I would suspect that either wrapping or inheriting from the Grid would be an excellent first choice. The panel could then manage the column definitions itself based on the number of items it contains.
To determine the layout of the individual items, I suspect using the ActualHeight to determine when another item would cause a column to overflow and using that to move to the next column would be the optimal solution. I would imagine using a single vertical stack panel with no border or padding inside each column may make it easier for your to offload the layout to those controls, but I believe you would still wind up having to determine which panel to lay the items out in based on the item heights.

Silverlight DataPager - Split Into 3X3?

I have a ListBox bound to an observable collection.
I also have a data pager bound to the itemsource of the list box.
I currently have the data pager set to only show up to 3 rows.
How would I go about changing the style ListBox style (or something else) such that I could have a 3X3 display? For example, the first three items in my observable collection would be displayed on the first row of the list box, horizontally next to each other, then the next row would contain the next three items in the observable collection?
Any info would be greatly appreciated.
Thanks.
Chris
It sounds like you want to use an ItemsControl with a WrapPanel (from the Silverlight Toolkit) in the ItemsPanelTemplate.
<ItemsControl xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Here's a short tutorial about the WrapPanel: http://blogs.silverlight.net/blogs/justinangel/archive/2008/11/05/silverlight-toolkit-wrappanel.aspx

Resizing Listbox Contents according to Listbox dimensions

I am attempting to resize the contents of my listbox according to the listbox itself. This is being done in WPF.
Any ideas on how this might be possible?
I assume when you say "resize" you mean that you want to stretch the items in both directions. To take a default ListBox and stretch the items horizontally all you need is:
<ListBox HorizontalContentAlignment="Stretch"/>
The default is Left so all the ListBoxItems end up pushed to the left and sized individually based on their content.
Vertical stretching requires getting rid of the StackPanel used to do layout for the items because it has no concept of resizing its children in the direction of Orientation. The simplest thing to use is a UniformGrid but you might want something more custom depending on how you want the items to size relative to each other. You'll also need to do the same thing with the VerticalContentAlignment setting (Center by default). So here's one that will stretch items both ways:
<ListBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

WPF ListBox Show WAIT Cursor?

I have a WPF ListBox that displays images loaded from a local folder,
usually somewhere between 1- 300).
I'm using a converter in my imageTemplate to make sure and show thumbnails of the images,
and not the images in their full size. Even while doing this, it still
can take several seconds to load initially.
My question is, how do I know in my ListBox when the loading of ListBoxItems
Begins/Ends, so that I can set the Mouse Cursor to a waiting status? I'm looking
for a way to notify that user that something is happening..
Here is what my ListBox looks like in XAML:
<ListBox SelectionMode="Extended"
ItemsSource="{Binding Path=ImageFiles}"
ItemTemplate="{StaticResource imageTemplate}"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.IsDeferredScrollingEnabled="False"
VirtualizingStackPanel.VirtualizationMode="Recycling"
x:Name="images">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Thanks!
I answered a similar question, here.
If you don't want to do a pop-up, you could also do something similar by attaching a translucent rectangle (or some other filling control), with a message/animation in front of it, to the listbox or its parent control that gets closed asynchronously like the popup in the linked answer does. I did something like that for Silverlight back before the BusyIndicator was available, and it worked quite well. I set it up as a user control with a property for the control it should cover, so it was easily re-used.

Resources