Need advice on customizing ListBox template - c#

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.

Related

C#/UWP OutOfMemory when change ListView to horizontal

I have a ListView with about 700 entries (one Image per entry). The ListView works just fine in vertical scroll mode. But when I change it to Horizontal it crashes on the phone with an OutOfMemory Exception.
I change the scroll direction with code from Microsoft:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
It seems like Lord Windows is trying to load the complete list at once when the Orienation is changed. Anyone else experience this issue, maybe even provide a solution?
By using StackPanel you loose virtualization. So all the 700 entries are in memory at once when you scroll the list. Use VirtualizingStackPanel or better, use GridView instead of ListView.

Single Row Horizontally Scrolling/Swipeable GridView

I wanted a single-row GridView that can be scrolled horizontally both with mouse and touch swipe. The GridView is to present images through binding so that a single image will be selected from an array of images.
Everything works fine (binding, image selection, etc.) except that the horizontal scroll doesn't work. The XAML code is shown below.
What am I missing?
<GridView x:Name="IconGridView"
Grid.Row="0"
Margin="8,12"
DataContext="{x:Bind IconManagerObj}"
DoubleTapped="{x:Bind IconGridView_DoubleTapped}"
IsItemClickEnabled="True"
IsSwipeEnabled="True"
ItemsSource="{Binding Path=IconImageInfo}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
SelectionMode="Single"
Tapped="{x:Bind IconGridView_Tapped}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="4,8"
HorizontalAlignment="Center"
BorderBrush="{ThemeResource SubtleBlueBrush}"
BorderThickness="1">
<Image Width="150" Source="{Binding IconImage}Stretch="Uniform"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
You have everything right but the Orientation for the ItemsWrapGrid must be Vertical in order to have an Horizontal ScrollViewer.
The documentation here https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.itemswrapgrid.aspx explains that:
When the value is Vertical, the grid adds items in columns from top to bottom, then wraps from left to right. Columns of items scroll or pan horizontally.
Juan Pablo Garcia Coello's answer put me on the right track but didn't work without an additional setting. The crucial thing I found out through trial was setting the Height for GridView.
Height must be set enough for a single row elements to display but not high enough to allow a second row. For image height of 100 I set this arbitrarily to 140 and works great.
ScrollViewer.VerticalScrollMode must be Disabled
ScrollViewer.HorizontalScrollMode must be Auto or Enabled
ScrollViewer.HorizontalScrollBarVisibility must be Auto or Enabled
The most crucial, as Juan indicated, the ItemsWrapGrid Orientation must be Vertical (sounds counterintuitive but works!)
I have marked Juan's as answered as it provides a complete answer with this one, due to the fact that I couldn't have quickly figured out a complete answer without the Orientation being set Vertical -- a rather counter-intuitive setting if you ask me but now I get it.

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>

Change how items are displayed WPF list box

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>

Categories