Change how items are displayed WPF list box - c#

I have a WPF window which displays a ListBox. I've changed the ListBox's item template so that the list box displays rectangular items which can be selected.
Now I'd like to modify the ListBox's ItemsPanelTemplate so that the items are displayed in a grid instead of either a vertical or horizontal list. Specifically I'd like the first item to go in the top right corner of the ListBox and then second item below it and third under that until the height of the next item would make the column of items taller than the height of the ListBox itself. At that point it should start a second column directly to the right of the first item added. If the total width of all of the columns combined was greater than width of the ListBox then a horizontal scroll bar should appear.
Is there a way to get that effect just by modifying the ItemsPanelTemplate or do I need to extend the ListBox class itself? In either case, how would I got about it?
Thanks for your help!

I haven't tested this, but I suspect you can get the desired effect by swapping out the default panel used by the ListBox to a WrapPanel:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

Related

WPF ListView does not keep the items into view when swiped

I have a Windows 8.1 Store application and in one of the views, I have a ListView that displays some items. Not all the items fit into the area where the ListView is displayed (inside a StackPanel). If I swipe up I get to see some of the items listed towards the bottom of my list, but those items do not stay into view. As soon as I release the list, it scrolls up again so that the first item in the list is listed at the top of the list. How can I prevent this annoying behavior? This is how my ListView is declared:
<ListView Name="ParametersListView" Height="Auto" Width="Auto"
ItemsSource="{Binding Source = {StaticResource parametersViewSource}}"
SelectionMode="Single" IsSwipeEnabled="True" IsItemClickEnabled="False">
I managed to find out what the problem was, though I have no explanation for it. I found this post on StackOverflow and according to one suggestion made there, if the container that holds the ListView does not restrict the size of the ListView control, then you can't scroll down the ListView. My ListView was placed in a vertical StackPanel but once I changed that and placed it into a Grid, all was fine. I set the Height for the Row where I placed the ListView to "*". My Grid has one other row that contains the header of the ListView.
Before, when the ListView was placed in a StackPanel, I didn't set the Height of the StackPanel and maybe that is why the behavior was the way it was.
This other post has more details and the first answer contains a detailed explanation of the issue.

Need advice on customizing ListBox template

I have a ListBox of CheckBox values, the number of values vary from time to time, it can be 10, 15, 100, etc..
I would like to customize the way the values are displayed. Currently, if I have 50 values, they are all displayed vertically, just one column.
I would like to have it such that, 1 column will have a maximum of 10 values, and I am able to scroll horizontally to view the values at other columns.
I tried using ItemsPanelTemplate with StackPanel orientation horizontal, but well, all values are now in 1 row.
Please advice.
Thanks!
You could try changing the panel used by your ListBox to a WrapPanel instead. Set its Orientation to Vertical, then size the height of the ListBox so it fits 10 items in each "column" before starting a new column.
<ListBox Height="..."
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
If you want 10 items in each column but don't want to explicitly set the height of the ListBox then the only solution I can think of is writing a custom Panel.

How UniformGrid work with infinite size

For example we have a ListBox with a UnidormGrid like a ListBoxPanel.
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}, Path=Items.Count}"></UniformGrid>
<!--<cntr:StackGrid Orientation="Horizontal" Direction="Normal"/>-->
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>4</Button>
</ListBox>
ListBox will give a infinite size to UniformGrid, but there is no any errors. UniformGrid will use only a visible size. How it do that? It will help me in bulding my own panel.
P.S. I know, that i can to disable ScrollView in ListBox and my panel will get a visible size.
As far as I know, the UniformGrid derives its cell size by the largest child it is displaying. It breaks the content to a new line when either its width or height is exceeded, according to the Orientation property. By default, it is set to Horizontal.
Which leads me to your question: why do you think that it has an infinite width? Sure, the ListBox contains a ScrollViewer in its default control template, but in my opinion it only provides vertical infinite space for the panel (horizontally, it is constrained to the width of the list box), which allows breaks for the default uniform grid to happen.
If you have any further questions, please feel free to ask.

make horizontal scrollable custom calendar

I want to make calendar in windows phone 8 using XAML/c#. It should like horizontal bar that has 7 days fit to screen. User can scroll these dates like on phone screen there are 1 to 7 dates and user can scroll to view more dates. If user tap on any date then its color should be changed. I was trying to implement longlistselector and listbox but could do successfully. I am newbie. please help.
Thanks
ongListSelector doesn't allows you to change scroll orientation. In other controls like the ListBox you can specify the property ItemsPanel to use a StackPanel with horizontal orientation. But that property is not available in LongListSelector (i don't know exactly the reason, but i think it might be something related with the complex grouping, jump list capabilities of the LongListSelector.
If you need to make an horizontal list and you don't need to group your data, you can replace the LongListSelector with a ListBox and use the ItemsPanel property to specify a horizontal stackpanel.
So, no issues.
You can of course use the ListBox instead of LongListSelector.
You can have it horizontally scrollable as follows:
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Your control... />
</DataTemplate>
</ListBox.ItemTemplate>

Trying to animate lines of a grid onto the screen in a WPF app and detect how many can fit on the screen at a time

I am creating a food menu that displays on a TV screen in a restaurant. There will be no interaction of the menu itmes, so I need to automatically display the items and rotate through them when all the items do not fit on the screen at one time.
I have all of the components of the project built, even the administration of what the menu items are and which day to display them. Now, I need to finish the display of the items for the TV screen(s).
I am new to WPF, so I'm trying to figure out the best way to do this:
Menu items are listed with the name of the item along with calories, protein, fat, and cholesterol. Because of this, they need to be displayed in a grid.
There is no user interaction with the menu, so I need to make sure that I can properly break up the list of items into "pages" that animate on and off the screen after displaying for several seconds. The way I was thinking of doing this was to add each item on the view and evaluate how much space is available beneath it. If the space is less than a certain height, the rest of the menu items are queued for display on the next "page". It would be nice to have each line item rapidly slide in from the left, having all of them appear on the screen within 1-2 seconds.
What is the best control to display them with? An ItemsControl, perhaps?
Any great ideas you guys have that can point me in the right direction will be greatly appreciated!
Update: Here's a very rough mockup of what I'm talking about:
You can probably get away with using a Grid or StackPanel and animate the margin value of your elements (use negative margins to slide items in). You need to ensure that the parent element has ClipToBounds set to false so that items can be drawn outside of its bounds.
To measure an element's height, just use the Measure method on the row element to figure out how much space it needs vertically. Based on that, you can determine how many elements you can fit in one page.
There's too much work to build everything, however the following should lead you to your goal :
Inherit from Listview add create a 'PartialListView' , with added dependencies properties StartIndex and ItemHeight. It should build a listview of the right height showing items from StartIndex to StartIndex+ItemHeight. (scroller not shown. Use FindDescendant (of type scrollviewer) to find the scrollViewer after listView is loaded, and set its VerticalOffset)
Create a UserControl with two dependency properties :
1) bind to an ObservableCollection of MenuItems (Item, Calories, ...)
2) an ItemHeight (integer property).
Then on each collection change you modify IndexList, an Observable collection of numbers {1, 6, 11 }, which are the first indexes of each menu.
The control code will look like :
<ListBox ItemsSource="{Binding IndexList, ElementName = mycontrolname}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<ScrollViewer x:Name="PageScroller" ... set to horizontal only, not
showing any bar >
<StackPanel Orientation="Horizontal" />
</ScrollViewer>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<app:PartialListView StartIndex="{Binding }"
IndexCount = "{Binding IndexCount, ElementName = mycontrolname}"
ItemsSource = "{Binding MenuItems , ElementName = mycontrolname}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
switching 'screen' will be done by changing the HorizontalOffset of the PageScroller ScrollViewer.

Categories