WPF Listview Display - wpf

I'm trying to display a Listview items through RectangleBox (Which I managed to do using ControlTemplate)
My problem is the how the RectangleBox are being organised on the window.
I'd like to display as many as I can on one line (Depending on the windows' width) and when one line is filled, go start a new one and so on.
The organisation would be updated depending on the window's width after each resize:
This might give a better idea of what I want, you see each RectangleBox (Labelled 1,2...) organisation on the window changing depending on its width.
Here is my current code in my MainWindow xaml:
<ListView Name="PlayerList" ItemsSource="{Binding Players}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Having the following Style applied:
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GroupBox Header="{Binding Name}" Width="250" Height="125" Name="Disp" HorizontalAlignment="Left">
<GroupBox.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5,0,0,0" TextAlignment="Right"></TextBlock>
</StackPanel>
</DataTemplate>
</GroupBox.HeaderTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Char}"/>
<TextBlock Text="{Binding Item}"/>
</StackPanel>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But so far, the UniformGrid was just a failled attempt, I've been looking around but couldn't really find a solution. Hopefully it was just me being dumb and missing something obvious D:
Thanks for the help.

Thanks for few comments.
WrapPanel was indeed the right way, just didn't think of it :P
I just needed to add the following property:
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
To my listview in order to avoid all the items to stack on one line.

Related

Wpf change the background colour of an expander's header only

I have looked at many questions/answers but couldn't find what I was exactly looking for,
I am trying to change the background colour of the expander's header only and not have the same colour continue for the content within the expander. Preferably within xaml but a vb.net solution would suffice.
(Any comments or suggestions will be helpful)
If this is a duplicated question please direct me to the answer and leave the question open to help others avoid the same issue in the future!
Thanks.
I am not sure whether this is what you are exactly looking for, but you could change the header background by simply doing that:
<Expander VerticalAlignment="Center">
<Expander.Header>
<Grid Background="LightBlue">
<TextBlock Text="Expander Header"/>
</Grid>
</Expander.Header>
<StackPanel>
<TextBlock Text="Cotent"></TextBlock>
</StackPanel>
</Expander>
Or you could override the default Expander's Header DataTemplate by using HeaderTemplate
<Window.Resources>
<DataTemplate x:Key="HeaderText">
<Border Height="25" Background="LightBlue">
<TextBlock Text="{Binding}"
Margin="4 0"
VerticalAlignment="Center"
Foreground="White"
FontSize="11"
FontWeight="Normal"
/>
</Border>
</DataTemplate>
<Style TargetType="{x:Type Expander}">
<Setter Property="HeaderTemplate" Value="{StaticResource HeaderText}"/>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Expander VerticalAlignment="Center" Header="Expander Header">
<StackPanel>
<TextBlock Text="Cotent"></TextBlock>
</StackPanel>
</Expander>
</Grid>
I had a lot of problems with getting the header background set.
I found the easiets weay to do it was to simply make a coloured rectangle and put it behind the expander. (use Margin and Height to make it fit)
<Rectangle Grid.Row="1" Grid.Column="0" Fill="LightBlue" Height="33" Margin="0,0,0,-35" />
or use a border if you want rounded corners:
<Border CornerRadius="15" Height="33" Margin="0,0,0,-35" Background="LightBlue" />

Silverlight Textblock inside Listbox causes it to expand instead of wrapping the text

I have something like this:
<ListBox ItemsSource="{Binding List}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Property}" TextWrapping="Wrap" Grid.Column="0"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the problem I'm having is that the TextBlock will expand the Grid column (and the Listbox) when the text is too long, instead of wrapping it as expected. Maybe I don't understand the star-sizing concept of Grids completely, but the way I see it, since the column width is set to "1*" which means "the remaining space available", the Textblock should NOT try to expand beyond this width, and should wrap the text instead.
So how can I fix this problem? By the way, I need the Grid (or some other container) because there will be other components besides the Textblock. Also the ItemContainerStyle section is there so that the Listbox element occupies the whole space.
Thanks in advance!
Try to add ScrollViewer.HorizontalScrollBarVisibility="Disabled" to your ListBox.
you don't need column definitions if it will be just one, try with the following:
<ListBox ItemsSource="{Binding List}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Property}" TextWrapping="Wrap" HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

WPF Using styles to change a ListBox WrapPannel to a ListBox StackPanel

I want to change a listview with a wrappanel inside into a listivew with a stackpanel inside, basically to switch between a "small image view" and a "details view".
Not sure the best way to do it though. What I have so far:
<UserControl.Resources>
<Style x:Key="ListBoxWrap" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListBoxList" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ListBox Style="{StaticResource ListBoxList}" Name="lstContacts" Background="White" Margin="7,0,7,7" Grid.Row="1" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="4" Margin="5">
<StackPanel>
<TextBlock Text="{Binding FullName}" Margin="5,3,5,0" />
<TextBlock Text="{Binding Title}" Margin="5,0,5,3" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
You should use a ListView for that, then you just need to swap out the ListView.View to change the appearance, the GridView already is a details-view, then you only need to create a view for the thumbnails.
To do so subclass ViewBase, there is an example in the documentation; creating a simple thumbnail view should not be very hard.
This approach has the advantage that it fully encapsulates the display-logic, so you should not need to swap out properties like ItemTemplate in addition to the panel.
You could also use a ItemTemplateSelector to modify the template based on a specific value change which could be (event) triggered by a mouse-over or click event.
All of this code would reside in the xaml and you would not need to create a separate class or custom control.

How as items listbox Horizontal Alignment Center?

A have listbox
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Button Content="{Binding name_trainer}" Tag="{Binding idPersonTrainer}" DockPanel.Dock="Top" HorizontalAlignment="Center">
</Button>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox HorizontalContentAlignment="Center">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding yourstuff}" FontSize="72"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
The accepted answer is right, however I needed a bit more:
not only to center, but also to horizontally stretch the items. Just changing HorizontalAlignment to Stretch didn't work, so, here's how it's done:
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch">
<StackPanel.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</StackPanel.Resources>
</StackPanel>
</ItemsPanelTemplate>
You may have to center the DockPanel, rather than the data inside it. I've seen this behavior with StackPanel, because the panel shrinks to the contents. The centering ends up working properly, but in the wrong context.

Silverlight: Set Items Widths in ItemsControl to Stretch

I've got an ItemsControl which fills from top to bottom, but I can't get it's child items to occupy the whole width of the ItemsControl:
I basically need to stretch the green bits to fill the width of the control (as shown by the blue bits).
I've tried things like setting the HorizontalAlignment property of the template item to Stretch and I've even tried binding it's Width property to the ItemsControl Width, but neither worked.
Should be a straight forward one, but it's something I just can't quite figure out...
Edit: here's the ItemTemplate (the whole thing is the ItemTemplate which itself contains an ItemsControl which is bound to a list of child objects):
<DataTemplate>
<Border CornerRadius="5" Background="#ddd">
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="18" Foreground="#bbb"/>
<ItemsControl ItemsSource="{Binding PlugIns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0,10,10" Tag="{Binding}"
MouseEnter="StackPanel_MouseEnter">
<Border Child="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</DataTemplate>
You need to configure the ListBoxItem HorizontalContentAlignment, you do this by using a Style object in the ListBox ItemContainerStyle as follows:-
<ListBox ....>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
OK, so as I continued to build the app up, I figured out how to resolve this. Essentially, when I changed the template of the ItemsControl to support scrolling, the items spanned to fill horizontally :)
<ItemsControl>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
...
</ItemsControl>

Resources