WPF Application Layout - Make DockPanel fill space of ListBox - wpf

I would like to make the "Cartoon" below to be aligned to the right and the yellow part to fill all the space in the middle of my ListBox item.
However, all I can get is this:
Here is my layout xaml:
<Window x:Class="Cartoons.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Cartoons" Height="350" Width="525" SizeToContent="Width">
<DockPanel x:Name="mainPanel">
<Border Background="Green" DockPanel.Dock="Bottom" Width="Auto" Height="Auto">
<Grid Margin="2" Height="Auto">
<ListBox Name="listBoxCartoons" SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel HorizontalAlignment="Stretch" Background="PowderBlue">
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue" DockPanel.Dock="Left" >
<Image Source="<IMAGE_LOCATION>" Width="64" Height="64" Stretch="Fill"/>
</DockPanel>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue" DockPanel.Dock="Right">
<TextBlock Text="Cartoon" VerticalAlignment="Center"/>
</DockPanel>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Yellow">
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<TextBlock Text="Character 1"/>
<TextBlock Text="Walt Disney"/>
<TextBlock Text="Speedy Gonzales"/>
</StackPanel>
</DockPanel>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</DockPanel>
</Window>
I have tried many things but regardless what I do, it is alwasy displayed with large white space to the right.
Much appreciated,

If you're not avoiding hard-coding numbers in, such as margins, you could try this (tested in Visual Studio for your convenience):
<Border Background="Green" DockPanel.Dock="Bottom" Width="Auto" Height="Auto">
<Grid Margin="2" Height="Auto">
<ListBox Name="listBoxCartoons" SelectionChanged="ListBox_SelectionChanged">
<ListBoxItem>
<!-- Width of the below element may have to be adjusted -->
<Grid HorizontalAlignment="Stretch" Width="499">
<Image Source="<IMAGE_LOCATION>" Width="64" Height="64" Stretch="Fill" HorizontalAlignment="Left"/>
<!-- Margin of the below element may have to be adjusted -->
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Stretch" Background="Yellow" Margin="69,8,0,8">
<TextBlock Text="Character 1"/>
<TextBlock Text="Walt Disney"/>
<TextBlock Text="Speedy Gonzales"/>
</StackPanel>
<Label Background="AliceBlue" Content="Cartoon" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
</ListBoxItem>
</ListBox>
</Grid>
</Border>
Also, there is an extra near the bottom of your XAML, above .

The problem is that the ListBox will generate container elements (of type ListBoxItem) for each item - these will, by default, align content to the left. To change that, add this to your ListBox:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>

I figured it out.
Needed to set HorizontalContentAlignment="Stretch" on ListBox.
That resolved the issue. Just modify above line
<ListBox Name="listBoxCartoons" SelectionChanged="ListBox_SelectionChanged">
to
<ListBox Name="listBoxCartoons" HorizontalContentAlignment="Stretch" SelectionChanged="ListBox_SelectionChanged">
and it worked.

Related

How to remove border from ListBox in WPF?

Here is my Code:
<Grid>
<ScrollViewer Grid.Row="0" Grid.Column="1" HorizontalScrollBarVisibility="Disabled">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBox MinWidth="80" Name="tbTodoName" Margin="5, 2"/>
<Button Content="Add" Height="30" Margin="5, 0"/>
</StackPanel>
<ListBox Name="lstTodo" ItemsSource="{Binding}" BorderThickness="0" Padding="0" ItemTemplate="{StaticResource TodoTemplate}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch">
</ListBox>
</StackPanel>
</ScrollViewer>
</Grid>
and here is a picture of what the program looks like:
As can be seen in the picture, a frame is displayed around the ListBox. I don't understand why, since I set BorderThickness and Padding = "0".
Can someone help me?
You have set a custom ItemTemplate, which is applied only to the items.
You will need to apply the Template as well:
<Grid>
<ScrollViewer Grid.Row="0" Grid.Column="1" HorizontalScrollBarVisibility="Disabled">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBox MinWidth="80" Name="tbTodoName" Margin="5, 2"/>
<Button Content="Add" Height="30" Margin="5, 0"/>
</StackPanel>
<ListBox Name="lstTodo" ItemsSource="{Binding}" BorderThickness="0" Padding="0" ItemTemplate="{StaticResource TodoTemplate}" Template={StaticResource ListBoxNoBorder}
ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch">
</ListBox>
</StackPanel>
</ScrollViewer>
</Grid>
And in your resource dictionary:
<ControlTemplate x:Key="ListBoxNoBorder" TargetType="{x:Type ListBox}">
<Border BorderBrush="Transparent" BorderThickness="0">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>

TextBlock Wrap and scrollView

The code below is working nice but the vertical ScrollBar is disabled even if large text inside of TextBlock. How can I enable it?
<UserControl.DataContext>
<viewModels:CommentsViewModel/>
</UserControl.DataContext>
<Grid>
<DockPanel >
<TreeView DockPanel.Dock="Top"/>
<Expander Header="Yo" DockPanel.Dock="Bottom" VerticalAlignment="Bottom">
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<TextBlock TextWrapping="Wrap" MaxHeight="250"
Text="{Binding Article.Article.Content}"/>
</ScrollViewer>
</Expander>
</DockPanel>
</Grid>
I found.
MaxHeight="250"
tag should be not in the TextBlock, but should be in the Grid to limit height. Then it will be working perfectly.
<UserControl.DataContext>
<viewModels:CommentsViewModel/>
</UserControl.DataContext>
<Grid>
<DockPanel >
<TreeView DockPanel.Dock="Top"/>
<Expander Header="Yo" DockPanel.Dock="Bottom" VerticalAlignment="Bottom">
<Grid MaxHeight="250">
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<TextBlock TextWrapping="Wrap"
Text="{Binding Article.Article.Content}"/>
</ScrollViewer>
</Grid>
</Expander>
</DockPanel>
</Grid>
If your just displaying text, to be certain it'll work use a TextBox:
<Expander Header="Yo" DockPanel.Dock="Bottom" VerticalAlignment="Bottom">
<Grid IsReadOnly="True">
<TextBox TextWrapping="Wrap" MaxHeight="250"
Text="{Binding Article.Article.Content}"/>
</Grid>
</Expander>

How can I wrap a custom text?

I have a listbox that uses datatemplates and one of the elements in the template is a textblock. Problem is that the words won't wrap, and I don't want to set a fixed size. Anybody that knows how to resolve this problem? It's driving me crazy!
<ListBox Grid.Row=" 1" HorizontalContentAlignment="Stretch" Background="#24221f" ItemsSource="{Binding Messages}" ScrollViewer.VerticalScrollBarVisibility="Visible" ClipToBounds="False" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate >
<Border BorderBrush="#24221f" BorderThickness="3" Width=" auto">
<DockPanel Background="{StaticResource blackBackground}" HorizontalAlignment="Stretch" Width="auto">
<Border BorderThickness="3" BorderBrush="Transparent">
<Image Source="{Binding IconImageUrl}" VerticalAlignment="top" Height="22" Width ="22" DockPanel.Dock="Left" />
</Border>
<Border BorderThickness="3" BorderBrush="LightGray" Height="auto" Width="auto" HorizontalAlignment="Left" VerticalAlignment="Center" DockPanel.Dock="Left">
<Image Source="{Binding ProfileImageUrl}" VerticalAlignment="Top" HorizontalAlignment="Left" Height="48" Width ="48" />
</Border>
<StackPanel Orientation="Vertical" DockPanel.Dock="Left" Margin="5,0,0,0">
<Label Content="{Binding Path=Sender}" Foreground="#feb41c" FontFamily="Verdana" FontWeight="Bold" FontSize="14" />
<TextBlock Width="100" Text="{Binding Path=ShortMessage}" Margin="10,0,0,0" Foreground="BlanchedAlmond" TextWrapping="Wrap" FontFamily="Verdana" />
<Label Content="{Binding Path=Time}" Margin="10,0,0,0" Foreground="DarkGray" FontFamily="Verdana" FontStyle="Italic"/>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
StackPanel is Evil :=) when i have strange behaviours in a xaml which include StackPanel, switching to a Grid with right parameters ( fixed sized, or stars or "Auto" ) often fix the issue.
Note also that there is an error in your xaml since you set the DockPanel.Dock of your first image (IconImageUrl) whereas it is in the border that surrrounds it that you should be setting it. That may get the Layout to do strange things.
just try with HorizontalContentAlignment property to "Stretch" of ListBoxItems using the Style
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
and also disable the HorizontalScrollBar visibility
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Update
<Window.Resources>
<SolidColorBrush x:Key="blackBackground" Color="Black"/>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<Grid>
<ListBox Grid.Row=" 1" HorizontalContentAlignment="Stretch" Background="#24221f" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Messages}" ScrollViewer.VerticalScrollBarVisibility="Visible" ClipToBounds="False" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate >
<Border BorderBrush="#24221f" BorderThickness="3" Width=" auto">
<DockPanel Background="{StaticResource blackBackground}" HorizontalAlignment="Stretch" Width="auto">
<Border BorderThickness="3" BorderBrush="Transparent">
<Image Source="{Binding IconImageUrl}" VerticalAlignment="top" Height="22" Width ="22" DockPanel.Dock="Left" />
</Border>
<Border BorderThickness="3" BorderBrush="LightGray" Height="auto" Width="auto" HorizontalAlignment="Left" VerticalAlignment="Center" DockPanel.Dock="Left">
<Image Source="{Binding ProfileImageUrl}" VerticalAlignment="Top" HorizontalAlignment="Left" Height="48" Width ="48" />
</Border>
<StackPanel Orientation="Vertical" DockPanel.Dock="Left" Margin="5,0,0,0">
<Label Content="{Binding Path=Sender}" Foreground="#feb41c" FontFamily="Verdana" FontWeight="Bold" FontSize="14" />
<TextBlock Text="{Binding Path=ShortMessage}" Margin="10,0,0,0" Foreground="BlanchedAlmond" TextWrapping="Wrap" FontFamily="Verdana" />
<Label Content="{Binding Path=Time}" Margin="10,0,0,0" Foreground="DarkGray" FontFamily="Verdana" FontStyle="Italic"/>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I think this thread answer's your question, see the accespted answer by "Nash" - Force TextBlock to wrap in WPF ListBox
( and remember to upvote the answer the the linked thread if it helps you :) )

WPF height and scroll at listbox - imposible

To keep things simple all i am trying to do is to place a listbox and a button below it. Although it seems simple it isn't. It is not, because it is in a GRID...
The row size is star size and listbox having verticalAlign top works great all the time. The problem is that I cannot add a button below it. Having a grid with 2 rows one star height and the other auto would place the button at the bottom of the form even if listbox contents are little. Trying to set both rows auto doesn't work when resizing as no scrollbar is visible at the listbox.... Any workaround for this??
Update some code
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel >
<ListBox DockPanel.Dock="Top" Name="lbStaff" ItemsSource="{Binding}"
Grid.Row="0" VerticalAlignment="Top" BorderThickness="0"
Background="WhiteSmoke" Margin="15,10,20,30" Style="{DynamicResource
ListBoxUsers}" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource
ListBoxTest1}"></Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Margin="5,4,5,4">
<TextBlock HorizontalAlignment="Stretch" FontSize="16"><Run
Text="{Binding Name}"/> - <Run Text="{Binding Mode=OneWay,
Path=PositionString}"/></TextBlock>
<TextBlock >Τηλέφωνο <Run Text="{Binding Phone}"/>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button DockPanel.Dock="Top" Grid.Row="0" HorizontalAlignment="Right"
VerticalAlignment="Top" Margin="0,10,7,0" Style="{DynamicResource
ButtonStyleNew1}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfApplication1;component/Images/filenew1.png"
Stretch="None" VerticalAlignment="Center"></Image>
<TextBlock Margin="5,0,0,0" FontSize="16">Προσθήκη Χρήστη</TextBlock>
</StackPanel>
</Button.Content>
</Button>
</DockPanel>
</Grid>
</Grid>
What i usually do is not using rows of grid but using DockPanel you can adjust the alignments by nesting each elements. But again it totally depends on the designer how they design that using grid row or any other way. What i got from the question the following code should help you out.
but if you post some code then we can figure out where the actual problem is.
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<ListBox Height="50"/>
</DockPanel>
<DockPanel DockPanel.Dock="Bottom">
<Button Height="20" DockPanel.Dock="Top"/>
<Label/>
</DockPanel>
</DockPanel>
</Grid>
So your problem here is that you have the in the ListBox you have ScrollViewer.VerticalScrollbars=Visible that make it collapsed if you dont want scrollbars and i would suggest not to use margins more in the designing. if you still have scroll bars remove the height of the ListBox and make the window larger. It all depends upon the size of the window if you don't have the size and proper alignment. Refining your code
<Window xmlns:my="clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
x:Class="MyLightWpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
xmlns:local="clr-namespace:MyLightWpfApplication.ViewModel"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<DockPanel >
<DockPanel DockPanel.Dock="Top" Width="400" Height="200">
<ScrollViewer DockPanel.Dock="Top" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ListBox Name="lbStaff" ItemsSource="{Binding AutoCompleteData}"
BorderThickness="0"
Background="WhiteSmoke" >
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel >
<TextBlock HorizontalAlignment="Stretch" FontSize="16"><Run
Text="{Binding FirstName}"/> - <Run Text="{Binding Mode=OneWay,
Path=PositionString}"/></TextBlock>
<TextBlock >Τηλέφωνο <Run Text="{Binding LastName}"/>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</DockPanel>
<DockPanel DockPanel.Dock="Bottom">
<Button DockPanel.Dock="Top" Height="30" Grid.Row="0">
<Button.Content>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="16">Προσθήκη Χρήστη</TextBlock>
</StackPanel>
</Button.Content>
</Button>
<Label/>
</DockPanel>
</DockPanel>
</Grid>
</Window>
Its all dependent on how much data you have in the ListBox. I have tried this code populating listbox with 20 rows its not showing scrollbars at all
You might try auto for both and put a MaxHeight on the ListBox but you still take a chance of pushing the button off the screen. Or put both in a ScrollViewer. Or can you live with the button on top?
I solved this problem using a dockpanel. I docked buttons at bottom and then i let listbox to fill the remaining area..(lastchildfill=true) ...
It works fine...

Set a border around a StackPanel.

Here's my XAML code:
<Window x:Class="CarFinder.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Search for cars in TuMomo" Height="480" Width="600">
<DockPanel Margin="8">
<Border CornerRadius="6"
BorderBrush="Gray"
Background="LightGray"
BorderThickness="2"
Padding="8">
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"
Height="25">
<TextBlock FontSize="14" Padding="0 0 8 0">
Search:
</TextBlock>
<TextBox x:Name="txtSearchTerm" Width="400" />
<Image Source="/CarFinder;component/Images/Chrysanthemum.jpg" />
</StackPanel>
</Border>
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"
Height="25">
</StackPanel>
</DockPanel>
</Window>
The border is set around the entire window. And also, when I create another StackPanel it's added to the right of my previous StackPanel instead of being added under it. What's the reason for this?
What about this one :
<DockPanel Margin="8">
<Border CornerRadius="6" BorderBrush="Gray" Background="LightGray" BorderThickness="2" DockPanel.Dock="Top">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="14" Padding="0 0 8 0" HorizontalAlignment="Center" VerticalAlignment="Center">Search:</TextBlock>
<TextBox x:Name="txtSearchTerm" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Image Source="lock.png" Width="32" Height="32" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</Border>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Height="25" />
</DockPanel>
You set DockPanel.Dock="Top" to the StackPanel, but the StackPanel is not a child of the DockPanel... the Border is. Your docking property is being ignored.
If you move DockPanel.Dock="Top" to the Border instead, both of your problems will be fixed :)
May be it will helpful:
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="160" Margin="10,55,0,0" VerticalAlignment="Top" Width="492"/>

Resources