ItemsControl with horizontal orientation
Simply change the panel used to host the items:
<ItemsControl ...>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
WPF ItemsControl horizontal orientation and fill parent?
So you want to proportionally stretch the items. If it is achievable at all with standard Panels, it's with Grid (which can have proportional columns), this would require setting ColumnDefinitions after the ItemSource changes.
It's simple with a custom Panel:
class ProportionallyStretchingPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement child in InternalChildren)
child.Measure(availableSize);
return availableSize;
}
protected override Size ArrangeOverride(Size availableSize)
{
double widthSum = 0.0;
foreach (UIElement child in InternalChildren)
{
widthSum += child.DesiredSize.Width;
}
double x = 0.0;
foreach (UIElement child in InternalChildren)
{
double proportionalWidth = child.DesiredSize.Width / widthSum * availableSize.Width;
child.Arrange(
new Rect(
new Point(x, 0.0),
new Point(x + proportionalWidth, availableSize.Height)));
x += proportionalWidth;
}
return availableSize;
}
}
<ItemsPanelTemplate>
<local:ProportionallyStretchingPanel"/>
</ItemsPanelTemplate>
StackPanel orientation not fully horizontal on ItemsControl
You did not change the layout of the items, only the layout of the ItemsControl
as a whole (which does almost nothing if there are no other elements in the same StackPanel
).
Use ItemsControl.ItemsPanel
to make the items layout horizontally.
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Orientation of StackPanel is not Working in ItemsControl (WPF)
You're actually creating a StackPanel for each item/Button. To get just one for all the items you need to set the ItemsPanel
of the control to a StackPanel.
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Text}" Tag="{Binding Text}" x:Name="New" Margin="5,0,5,0" Click="New_Click" />
</DataTemplate>
</ItemsControl.ItemTemplate>
Scrolling in horizontal ItemsControl
<ItemsControl ItemsSource="{Binding Data, ElementName=myWindows}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- Add this Template -->
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer HorizontalScrollBarVisibility="Visible">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<!-- ... Etc ... -->
</ItemsControl>
Align items in ItemsControl horizontally (no xaml)
Let`s try to use property Orientation like in here: ItemsControl with horizontal orientationh-horizontal-orientation
Here is an example:
var itemsControl = new ItemsControl();
var factoryPanel = new FrameworkElementFactory(typeof(StackPanel));
factoryPanel.SetValue(Panel.IsItemsHostProperty, true);
factoryPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
var template = new ItemsPanelTemplate {VisualTree = factoryPanel};
itemsControl.ItemsPanel = template;
Horizontal stackpanel to wrap DataBinded ItemsControl
I have solved this issue by setting Width for WrapPanel. In below snippet i have binded WrapPanel width to its Parent Grid control named MainGrid and Path to its ActualWidth. Please see below snippet will helps you sometimes to solve your issue
<ItemsControl Name="ThemesItemControl"
Grid.Column="1"
Grid.Row="1"
ItemsSource="{Binding InstalledCollection}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0.5">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
VerticalAlignment="Top"
Width="{Binding ElementName=MainGrid, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Width="210"
Height="260"
Margin="20"
Tag="{Binding ID}"
Command="{Binding DataContext.ThemeSelectCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}}}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<Image Source="{Binding TileImage}"/>
</StackPanel>
</Button>
<TextBlock Text="{Binding Title}"
FontWeight="ExtraBold"
HorizontalAlignment="Center"
FontSize="15"
FontFamily="Segoe Print"
Foreground="Red"/>
<TextBlock Text="{Binding Description}"
HorizontalAlignment="Center"
FontSize="13"
FontFamily="Segoe Print"
Foreground="Red"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Horizontally centered horizontal ItemsControl
About the closest you could get without writing your own panel would be:
<ItemsControl ItemsSource="{Binding TheItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.HorizontalAlignment" Value="Center"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Note that I'm .NET-less at the moment so cannot test the above.
Horizontal orientated WrapPanel within ItemsControl lists vertically
I think its because you are adding each image item to a new WrapPanel
in GameImagesTemplate
, you should just have to set the ItemsControl
ItemsPanelTemplate
to WrapPanel
in the GameTemplate
Example:
Xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="252.351" Width="403.213" Name="UI" >
<Window.Resources>
<DataTemplate x:Key="GameImagesTemplate" >
<StackPanel>
<Image Source="{Binding FileInfo.FullName}" Margin="8,8,8,8" Height="70" Width="70" />
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="GameTemplate">
<StackPanel>
<Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" />
<ItemsControl x:Name="imageContent" ItemsSource="{Binding FileList}" ItemTemplate="{StaticResource GameImagesTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding ElementName=UI, Path=FileList}" Grid.Column="0" ItemTemplate="{StaticResource GameTemplate}" />
</ScrollViewer>
</Grid>
</Window>
Code:
public partial class MainWindow : Window
{
private ObservableCollection<Foo> _fileList = new ObservableCollection<Foo>();
public MainWindow()
{
InitializeComponent();
foreach (var item in Directory.GetDirectories(@"C:\StackOverflow"))
{
FileList.Add(new Foo
{
Name = item,
FileList = new ObservableCollection<Bar>(Directory.GetFiles(item).Select(x => new Bar { FileInfo = new FileInfo(x) }))
});
}
}
public ObservableCollection<Foo> FileList
{
get { return _fileList; }
set { _fileList = value; }
}
}
public class Foo
{
public string Name { get; set; }
public ObservableCollection<Bar> FileList { get; set; }
}
public class Bar
{
public FileInfo FileInfo { get; set; }
}
Result
Buttons should align horizontal in ItemsControl.ItemTemplate
An ItemsControl uses another panel inside (by default it's a VirtualizingStackPanel
with vertical orientation) - you can change this via the ItemsControl.ItemPanel
property. That's why the StackPanel
that surrounds the ItemsControl
does not affect the alignment of your buttons. You should use the following code:
<DockPanel DataContext="{StaticResource ResourceKey=MainFrameViewModel}">
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="2">
<ItemsControl ItemsSource="{Binding PageViewModels}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType= DockPanel}}"
CommandParameter="{Binding }"
Width="200" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</DockPanel>
If you want to learn more about ItemsControls, I would recommend the great series of blog posts "ItemsControl: A to Z" by Dr. WPF: http://drwpf.com/blog/itemscontrol-a-to-z/
If you have any further questions, please feel free to ask.
Related Topics
How to Catch All Exceptions/Crashes in a .Net App
Datagridview: How to Set a Cell in Editing Mode
Convert Datetime to Julian Date in C# (Tooadate Safe)
Generic C# Code and the Plus Operator
Using Tfs API, How to Find the Comments Which Were Made on a Code Review
Interesting "Params of Ref" Feature, Any Workarounds
How to Get the Value of Private Field Using Reflection
How to Confirm That Mail Has Been Delivered or Not
Task<> Does Not Contain a Definition for 'Getawaiter'
Is the C# Compiler Smart Enough to Optimize This Code
How to Bring Up the Built-In File Copy Dialog
Read from Word Document Line by Line
@(At) Sign in File Path/String
How to Force C# .Net App to Run Only One Instance in Windows