Resizeable WPF ListBox / ItemsControl items - wpf

I would like to have GridSplitter-like functionality in a WPF ListBox (or ItemsControl). The following code doesn't work but demonstrates what I want to achieve:
<ListBox ItemsSource="{Binding MyCollection}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding MyTextProperty}" Margin="0,0,10,0"/>
<GridSplitter
Width="5"
Background="Red"
HorizontalAlignment="Right"
ResizeBehavior="CurrentAndNext"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Does anyone have an idea on how to implement this?

Why not use ListView GridView? GridView supports resizing columns.

Related

User Controls Wrapped inside a panel MVVM

I am new to WPF/Xaml and searched for this issue I am facing but found it tough. Requesting some help on this.
I need to display usercontrols (DATABOUND) (horizontally) inside a panel/listview so that they wrap when the width of listview/panel is met, with a vertical scroll bar autoshown (as in figure).
so far I have this code.
<ListView Grid.Row="3"
ItemsSource="{Binding Controls}"
VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"
>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,10"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="Focusable" Value="False" />
</Style>
</ListView.ItemContainerStyle>
<!--<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" VerticalContentAlignment="Bottom"/>
</DataTemplate>
</ListView.ItemTemplate>-->
</ListView>
I have even tried the below code. Yes, it wraps but no scrollbar appears!
<ItemsControl Grid.Row="3"
Width="100" Height="200"
ItemsSource="{Binding Controls}"
VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Margin="0,0,0,10"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Note: I am okay with any control that makes this happens. Not necessarily be a listview.
To wrap items you need to set ItemsPanel to WrapPanel, like in second example, but you may need to disable horizontal scrolling on ListView:
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" .../>
also, if you want to use ItemsControl then ScrollViewer is not part of default Template, like for ListView, so you'll need to wrap in in ScrollViewer
<ScrollViewer Grid.Row="3">
<ItemsControl ...>
<!-- .... -->
</ItemsControl>
</ScrollViewer>
and don't forget to move Grid.Row="3" from ItemsControl definition to ScrollViewer
You were close :-)
Put your listview with a view panel that is a wrapanel inside your scrollviewer.
<ScrollViewer>
<ItemsSource="{Binding Controls}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
You are using Wrap panel so you need to specify the width it supposed to take... since wrappanel is inside a items host control wrap panel itself cannot calculate the width.It will try to take all the width with respective to Orientation (in your case its horizontal)
Here is the sample code with list box as items host... in this code i have binded the wrappanel width to the actual width of the list box so that it will never take more width than the list box and also i disabled the horizontal scrolling which you don't need for horizontal orientation and vertical wrapping
Note: Make sure to change item template before using following code and it will work with all items hosts like ListView, ItemsControl...
<ListBox Width="500" Height="500" Name="listbox" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="{Binding ActualWidth,ElementName=listbox}"></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="100" Width="100">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
For ItemsControl
<ItemsControl Grid.Row="3"
Width="100" Height="200"
ItemsSource="{Binding Controls}"
VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"
Name="listbox"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="{Binding ActualWidth,ElementName=listbox}"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Height="30" Width="30">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

How to set WrapPanel itemsource to list?

I want to show in WrapPanel a list of images. How can I do that or maybe I shall use other control ?
You can absolutely use the WrapPanel to show a list of images, scrolling vertically or horizontally. To get the kind of panoramic tile effect like in People hub with your images, you could do something like this:
<controls:PanoramaItem Header="something" Orientation="Horizontal" Margin="0,-15,0,0" >
<ListBox Name="SomeList" Margin="0,0,-12,0" ItemsSource="{Binding SomeItemsList}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel x:Name="wrapPanel" Width="700" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,17">
<Image Height="200" Width="200" Margin="12,0,9,0" Source="{Binding ImageURL}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>
Please note that a WrapPanel inside a ListBox does pick up the DataTemplate you define .. so you have complete liberty to bind any list to your WrapPanel.
Hope this helps!
Search for the same thing and came across this: Displaying a Collection of Items in a WrapPanel.
<ItemsControl ItemsSource="{Binding ActorList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}" Height="100"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
or you can use Xceed's SwitchPanel.
Yes definetly not the WrapPanel, it has not ItemsSource, it can't take a list.
Use the ListBox, and you can set the ItemsSource.
Edit

Move down overflow contents in horizontal stackpanel

I have a list box in expander:
<ListBox ItemsSource="{Binding MySource">
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding MyContent}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
I wrap the radio button with horizontal orientation stackpanel. I want the overflow radio buttons move down like right image shown below (no horizontal scrollbar). Now, mine is like the left one.
Stackpanel Orientation="Horizontal" http://www.empirepic.com/images/i8f5sevyzqch10uodso.jpg
You need to use a WrapPanel, not a StackPanel. In WPF it's built into the main assemblies but in Silverlight you'll need to get the Silverlight Toolkit.
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding MySource">
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding MyContent}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<t:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

What is the difference between ItemTemplate and ItemPanelTemplate?

In WPF Listbox, I'm confused with these 2 notions:
ItemTemplate and ItemsPanelTemplate
Can someone explain me more?
Thanks
John
Let me try to explain this by example:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="SteelBlue" Padding="5" BorderBrush="Black"
BorderThickness="1" Margin="0,2">
<TextBlock Text="{Binding}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="DarkKhaki"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
And the result:
The ItemTemplate determines the layout of each item in the list. On the other hand the ItemsPanel is the panel that will contain the individual items. Given the above definition the visual tree will be something similar to this:
<StackPanel>
<Border>
<TextBlock Text="Alpha"/>
</Border>
<Border>
<TextBlock Text="Beta"/>
</Border>
....
</StackPanel>
ItemTemplate is used to specify a DataTemplate used to render the item in your ListBox.
ItemPanelTemplate is used to specify the panel used to arrange the children of your ListBox.
For example, if your ListBox is bound to an ObservableCollection you must specify a DataTemplate to tell it how to render each Person object.
<ListBox ItemsSource={Binding Persons}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text={Binding FirstName}/>
<TextBlock Text={Binding LastName}/>
<TextBlock Text={Binding Age}/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
That will arrange each item vertically because ListBox used a StackPanel by default. If you want to change this behaviour, used the ItemPanelTemplate property:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
You can even change the StackPanel to any other panel (WrapPanel for example).

WPF ListBox that lays out its items horizontally

I'm trying to write a WPF application for displaying images from a selection.
I want to display all of the available images in a banner along the top of the window, and display the main selected image in the main window for further processing.
If I wanted the list on the Left of the window, displaying the images vertically, I can do this quite elegantly using databinding.
<ListBox
Name="m_listBox"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="60" Stretch="Uniform" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is there a straightforward way I can make this horizontal instead of vertical?
The main requirements of a solution is:
The items are populated using databinding
The selected item is changed simply by the user clicking it.
WrapPanel
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>listbox item 1</ListBoxItem>
<ListBoxItem>listbox item 2</ListBoxItem>
<ListBoxItem>listbox item 3</ListBoxItem>
<ListBoxItem>listbox item 4</ListBoxItem>
<ListBoxItem>listbox item 5</ListBoxItem>
</ListBox>
WPF Tutorial
The default ItemsPanel for the ListBox control is a VirtualizingStackPanel, so if you want the normal, default experience for the control but just have it laid out horizontally, you should specify this (and change the orientation).
Example:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Here is example of StackPanel.
Horizontal Breadcrumb with Mvvm binding
<ItemsControl
x:Name="tStack"
Grid.Row="1"
Grid.Column="0"
Height="40"
Background="Red"
ItemsSource="{Binding BreadCrumbs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Margin="5"
CommandParameter="{Binding .}"
Command="{Binding BreadcrumbClickCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.BreadcrumbClickCommand}"
Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Resources