Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys,

I'm looking for a little direction here. I'm working on an application which needs to have a ListBox control with a fixed view of, say, 3x2 cells. These 3x2 cells would be updated depending on the scroll of the view. For instance:

+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 4 | 5 | 6 |
+---+---+---+


If the ListBox ItemsSource contains more than 6 records, I would like only the first 6 (as above) to be displayed. When the user navigates (likely through keyboard presses) to the bottom row and chooses to navigate down, it should display the next 6 cells:

+---+---+---+
| 7 | 8 | 9 |
+---+---+---+
| 10| 11|   |
+---+---+---+


In this example I have left the sixth cell blank to indicate that only 11 models exist within the ItemsSource of the ListBox. I had an original implementation which was using a "rolling DataContext" which was calculating what items to display programmatically, and updating the view. However, this has become too unreliable as I've introduced filtering and sorting mechanisms.

Can anyone think of a way this might be achieved? I've been scratching my head for hours now, and no amount of Googling is helping at all.

Thanks in advance!
Chris

What I have tried:

Used a UniformGrid within the ListBox as the panel
Used a rolling DataContext programmatically
Used Google high and low to find an answer
Posted
Updated 19-Apr-16 5:45am

1 solution

Not quite what you're describing, but very similar.

The resultant list is scrollable, but not constrained to whole lines, so it can be shown with 1/2 line, 1 line, 1/2 line in your example.

1. Set the ScrollViewer.HorizontalScrollBarVisibility attached property of the listbox to false.

2. Add an ItemsPanelTemplate to your list box as follows:
XML
<listbox itemssource="{Binding Entries}" scrollviewer.horizontalscrollbarvisibility="Disabled">
  <listbox.itemspanel>
    <itemspaneltemplate>
      <wrappanel />
    </itemspaneltemplate>
  </listbox.itemspanel>
  ...
</listbox>

This makes the list box use a wrap panel to layout items. It was necessary to disable the horz scroll bar in step (1) to prevent this placing all items on one line.

3. Define an item template for the list box items. The following worked on a simple test.

XML
<listbox.itemtemplate>
  <datatemplate>
    <grid width="100" height="100">
      <grid.rowdefinitions>
        <rowdefinition height="2*" />
        <rowdefinition height="*" />
      </grid.rowdefinitions>
      <textblock grid.row="0" text="{Binding Title}" horizontalalignment="Center" fontsize="36" />
      <textblock grid.row="1" text="{Binding Description}" horizontalalignment="Center" />
    </grid>
  </datatemplate>
</listbox.itemtemplate>


The result is a list box that lays out along each row, then wraps to the next line.
 
Share this answer
 
Comments
Chris Copeland 19-Apr-16 12:03pm    
That's almost what I need. I've managed to improve the current state of the control using a UniformGrid with a column definition:

<pre lang="c#"><ItemsPanelTemplate>
<UniformGrid Columns="9" IsItemsHost="True"/>
</ItemsPanelTemplate></pre>

This does resize the column widths to the correct percentile to fill the horizontal space, however the rows (as you mentioned) do overlap slightly. I'm seeing a small (perhaps 50 or 100 pixels) of the next row within the ListBox. The only question is, is it possible to make the rows stretch vertically as well as the equal stretch horizontally.

Thanks!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900