I need Horizontal view of list boxes - wpf

I am working on list boxes in WPF. I want to show the list boxes in horizontal direction. My code is
<Grid>
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="list" >
<ItemsControl.ItemTemplate>
<HierarchicalDataTemplate>
<Border Padding="5,0,0,2">
<WrapPanel Orientation="Horizontal">
<ListBox Name="mylistBox" Width="200" Height="200">
<Label Content="{Binding name}"/>
<Label Content="{Binding phone}"/>
<Label Content="{Binding email}"/>
<TextBox Name="NameTxt" Width="20" Height="20" Text="{Binding Path=Contact1.name}"></TextBox>
</ListBox>
</WrapPanel>
</Border>
</HierarchicalDataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
and my program looks like in the picture (Vertical)
Can anyone tell me how I can change the view?
thanks in advance.

<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="list" ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<HierarchicalDataTemplate>
<Border Padding="5,0,0,2">
<ListBox Name="mylistBox"
Width="200"
Height="200">
<Label Content="{Binding name}" />
<Label Content="{Binding phone}" />
<Label Content="{Binding email}" />
<TextBox Name="NameTxt"
Width="20"
Height="20"
Text="{Binding Path=Contact1.name}" />
</ListBox>
</Border>
</HierarchicalDataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

Your itemscontrol doesn't provide a custom ItemsPanel, then a StackPanel is used as a default with vertical Orientation.
Try add:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

You can either use a WrapPanel or a StackPanel depending on your requirements.
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
The documentation for IsItemsHost has an example of a horizontal list box.

Try a WrapPannel, which will lay the items out horizontally until there is no more room, and then move to the next line.
You also could use a UniformGrid, which will lay the items out in a set number of rows or columns.
The way we get the items to arange using these other panels in a ListView, ListBox, or any form of ItemsControl is by changing the ItemsPanel property. By setting the ItemsPanel you can change it from the default StackPanel that is used by ItemsControls. With the WrapPanel we also should set the widths as shown here.
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>

I post this answer because of informational purposes as an alternative way of doing things:
Entities/Classes:
public class Person
{
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public Contact Contact1 { get; set; }
}
public class Contact
{
public string Name { get; set; }
}
Code Behind:
Persons = new List<Person>( );
for ( int i = 0; i < 15; i++ )
{
Persons.Add( new Person( )
{
Name = String.Format( "Name {0}" , i ) ,
Phone = String.Format( "Phone 0000000-00{0}" , i ) ,
Email = String.Format( "Emailaddress{0}#test.test" , i ) ,
Contact1 = new Contact { Name = String.Format("Contact name = {0}", i) }
} );
}
list.DataContext = Persons;
Xaml proposal 1:
<ListBox x:Name="list" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Label Content="{Binding Path=Name}"/>
<Label Content="{Binding Path=Phone}"/>
<Label Content="{Binding Path=Email}"/>
<TextBox Height="20" DataContext="{Binding Path=Contact1}" Text="{Binding Path=Name}" Width="110"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Xaml proposal 2:
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ItemsControl x:Name="list" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ListBox>
<Label Content="{Binding Path=Name}"/>
<Label Content="{Binding Path=Phone}"/>
<Label Content="{Binding Path=Email}"/>
<TextBox Height="20" DataContext="{Binding Path=Contact1}" Text="{Binding Path=Name}" Width="110"/>
</ListBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>

Related

How to design a table that has dynamic columns with ItemsControl or ListView or DataGrid?

I want to design a table like picture:
The table has 4 row ,first column is row header, when click "Add column" button, a ColumnConfiguration will be added to ColumnConfigurations and last column will be deleted when i click "delete column" button, corresponding to add and delete a column in table
public ObservableCollection<ColumnConfiguration> ColumnConfigurations { get; set; }
I want something like:
<ItemsControl
BorderThickness="0"
HorizontalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="True"
MaxWidth="500"
Height="Auto"
VerticalContentAlignment="Top"
ItemsSource="{Binding ColumnConfigurations}"
AlternationCount="{Binding ColumnConfigurations.Count}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" Width="Auto" Height="Auto"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal" />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type dialogs:ColumnConfiguration}">
<StackPanel Orientation="Vertical">
<TextBlock Margin="4,0" Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource TemplatedParent},
StringFormat=Column {0}}" />
<TextBlock Margin="4,0" Text="{Binding ColumnType}" />
<TextBlock Margin="4,0" Text="{Binding Unit}" />
<TextBlock Margin="4,0" Text="{Binding Option}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Grid.IsSharedSizeScope="true" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Please give me a solution
Use DataGrid with AutoGenrateColumns="False", set your Columns directly.
DataGrid is what you are looking for:
https://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid(v=vs.110).aspx

WPF - The buttons next to each other

I have button and under him is text and these buttons are next to each other but are served under him. This is my code:
UserView.xaml:
<WrapPanel Orientation="Horizontal" HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path = Users}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Vertical">
<Button Style="{StaticResource UserButton}" Content="{Binding Name}"></Button>
<Rectangle Style="{StaticResource UserButtonStatus}"
Fill="{Binding Color}" ToolTip="{Binding Tooltip}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</WrapPanel>
MainWindow.xaml:
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical">
<TextBlock Style="{StaticResource Title}">Users</TextBlock>
<view:UserView x:Name="UserView">
<view:UserView.DataContext>
<Binding Path="UserViewModel" Source="{StaticResource ServiceLocator}"/>
</view:UserView.DataContext>
</view:UserView>
</StackPanel>
Required:
Actual (wrong):
You need to overwrite the items controls panel
items control will display each item underneath each other by default.
here is the code to add make sure its inside your items control tab just like you have done with the item template:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
So your userview.xaml will look like this:
<ItemsControl ItemsSource = "{Binding Path = Users}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Vertical">
<Button Style="{StaticResource UserButton}" Content="{Binding Name}"></Button>
<Rectangle Style="{StaticResource UserButtonStatus}" Fill="{Binding Color}" ToolTip="{Binding Tooltip}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Binding ItemsControl to ScrollViewer

At the begining I'll show some code:
private ObservableCollection<otwarteBezStolika> otwarteBezStolika = new ObservableCollection<otwarteBezStolika>();
public ObservableCollection<otwarteBezStolika> listunia
{
get { return otwarteBezStolika; }
set { otwarteBezStolika = value; }
}
}
public class otwarteBezStolika
{
public string number { get; set; }
public string date { get; set; }
public int orderID { get; set; }
public decimal price { get; set; }
public decimal priceR { get; set; }
public string opisRach { get; set; }
public string sum { get; set; }
}
And now in xaml:
<Window.Resources>
<DataTemplate x:Key="dataTempl">
<Border BorderBrush="Coral" BorderThickness="1" Width="170">
<Button Name="goToPOS" Tag="{Binding orderID}" Click="goToPOS_Click" Style="{StaticResource TabCloseButtonStyle}" Margin="1">
<StackPanel>
<Label Content="{Binding number}" HorizontalAlignment="Center" FontSize="15" FontWeight="ExtraBold" HorizontalContentAlignment="Center"></Label>
<Border BorderBrush="Turquoise" BorderThickness="1" Width="170"></Border>
<Label Content="{Binding date}" FontSize="12" HorizontalAlignment="Center"></Label>
<TextBlock Text="{Binding opisRach}" FontStyle="Italic" FontSize="12" Foreground="Black" TextAlignment="Center" TextWrapping="Wrap" Margin="0,0,0,2"></TextBlock>
<Border BorderBrush="WhiteSmoke" BorderThickness="1" Width="170"></Border>
<Label Content="{Binding sum}" FontSize="19" HorizontalAlignment="Center"></Label>
</StackPanel>
</Button>
</Border>
</DataTemplate>
<DataTemplate x:Key="mainTemplate">
<StackPanel>
<ItemsControl x:Name="imageContent" ItemsSource="{Binding listunia}" ItemTemplate="{StaticResource dataTempl}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</Window.Resources>
Grid:
<Grid Grid.Row="0">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="templ" ItemsSource="{Binding ElementName=UI, Path=listunia }" ItemTemplate="{StaticResource mainTemplate}" />
</ScrollViewer>
</Grid>
Problem is that I cannot see any item (I'm filling items using sqldatareader, and adding them to list - by the way, does DataTable will also work? So instead while(rdr.Read()) i could ouse SqlDataAdapter sda and sda.fill(Datatable))
Second problem is that, it does work when I put "dataTempl" inside scrollviewer ,like :
<Grid Grid.Row="0">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="templ" ItemsSource="{Binding ElementName=UI, Path=listunia }" ItemTemplate="{StaticResource dataTempl}" />
</ScrollViewer>
</Grid>
but items are show vertically, but I need to see them from left to right horizontal.
Thanks for answers!
Try doing this.. you dont need maintemplate.
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="templ" ItemsSource="{Binding ElementName=UI, Path=listunia }" ItemTemplate="{StaticResource dataTempl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
OR you can simply use:
<ListBox Name="templ" ItemsSource="{Binding ElementName=UI, Path=listunia }" ItemTemplate="{StaticResource dataTempl}">
</ListBox>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="kaloo" DisplayMemberPath="Name" ss:DragDrop.IsDragSource="True" ss:DragDrop.IsDropTarget="True" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ScrollViewer>

Horizontal stackpanel to wrap DataBinded ItemsControl

I have an ItemsControl for which the ItemsSource is Binded. i coded it as per the below so that it would add the UserControl (showing the different items) to a StackPanel with a horizontal orientation that then contains a wrappanel to wrap the items inside but it is not working. All of the items are showing but they are all on one line and do not wrap to a new line when needed.
How can this code be fixed to include wrapping?
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto"
Grid.Column="0" Grid.Row="1">
<ItemsControl x:Name="tStack"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1"
ItemsSource="{Binding Items.View}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel x:Name="stckPnl" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<WrapPanel>
<Viewbox HorizontalAlignment="Left" Height="400">
<Controls1:MyItemsUserControl Padding="5"/>
</Viewbox>
</WrapPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
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>

WPF Nested Databinding

I'm trying to bind data into nested StackPanels in WPF using the following code - to no avail. Can anybody spot where I'm going wrong?
<Page.Resources>
<DataTemplate x:Key="MinuteTimeSlotTemplate">
<TextBlock Text="{Binding Path=TourName}" Background="Blue" />
</DataTemplate>
<DataTemplate x:Key="HourlyTimeSlotTemplate">
<StackPanel>
<Border Height="120" BorderThickness="0,0,0,1" BorderBrush="#DDD" x:Name="parentRow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="123"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0" MouseUp="StackPanel_MouseUp_1">
<TextBlock Foreground="#4585B9" FontWeight="Bold" FontFamily="Trebuchet MS" FontSize="20" HorizontalAlignment="Right">
<Run Text="{Binding Path=Time}"/></TextBlock>
<TextBlock FontFamily="Trebuchet MS" Foreground="#808080" HorizontalAlignment="Right"><Run Text="View Bookings"/></TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="10,0,10,0" x:Name="stk">
<ItemsControl ItemTemplate="{StaticResource MinuteTimeSlotTemplate}" ItemsSource="{Binding Path=HourlySlots}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
</Page.Resources>
<helpers:AnimatedScrollViewer x:Name="scrlHours" Grid.Column="1" PanningMode="Both" PanningDeceleration="5" PanningRatio="2">
<ItemsControl x:Name="TimeSlotList" ItemTemplate="{StaticResource HourlyTimeSlotTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</helpers:AnimatedScrollViewer>
I set the parent StackPanels ItemsSource in code:
public HourlyCalendar() {
InitializeComponent();
TimeSlotList.ItemsSource = new Models.TimeSlots(DateTime.Today).HourlySlots;
}
And here's my model:
public class TimeSlots {
public TimeSlots(DateTime? day) {
this.HourlySlots = DataManager.GetCalendarDayTimeSlots(day);
}
public IEnumerable<TimeSlot> HourlySlots { get; set; }
}
The parent StackPanel binds as expected, but I cannot figure out how to bind the child StackPanel...
Turns out it was rather simple:
<helpers:AnimatedScrollViewer x:Name="scrlHours" Grid.Column="1" PanningMode="Both" PanningDeceleration="5" PanningRatio="2">
<ItemsControl x:Name="TimeSlots">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="120" BorderThickness="0,0,0,1" BorderBrush="#DDD" x:Name="parentRow">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0" Width="123" MouseUp="StackPanel_MouseUp_1"> <!--Height="{Binding Height, ElementName=parentRow}"-->
<TextBlock Foreground="#4585B9" FontWeight="Bold" FontFamily="Trebuchet MS" FontSize="20" HorizontalAlignment="Right">
<Run Text="{Binding Path=Time}"/></TextBlock>
<TextBlock FontFamily="Trebuchet MS" Foreground="#808080" HorizontalAlignment="Right"><Run Text="View Bookings"/></TextBlock>
</StackPanel>
<ListView ItemsSource="{Binding Bookings}" ScrollViewer.CanContentScroll="False">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TourName}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</helpers:AnimatedScrollViewer>

Resources