WPF disable ListBox autosizing in uniform grid - wpf

i do have the following structure:
<UniformGrid HorizontalAlignment="Stretch" Grid.Row="0" VerticalAlignment="Top" Columns="6" DockPanel.Dock="Right" >
<StackPanel HorizontalAlignment="Stretch">
<DockPanel Background="#FF393939" >
<Label Content="{lex:Loc Site}" Foreground="#FFE0E0E0"/>
</DockPanel>
<ListBox Height="300" ItemsSource="{Binding Sites.View}" DisplayMemberPath="Name.ActualTranslation">
</ListBox>
</StackPanel>...
These stackpanels in my UniformGrid should be spreaded over the whole MainWindow (or View)... Still if there is an item in a Listbox which has a longer string which needs more place than the standard width it autofits the string and i have to scroll vertically.
I dont want the listview to gain the width if the content has not enough place.
I also have a scrollviewer in my MainWindow in which this view is placed...
What can i do that the uniform grid stays the same width like the MainWindow-...
I've already tried to give a name to the MainWindow and Bind the width to something like this: Width="{Binding ElementName=MainWindow, Path=ActualWdith}" ..
though i get the error:
Cannot find source for binding with reference 'ElementName=MainWindow'. BindingExpression:Path=ActualWdith; DataItem=null;
What can i do to fix this issue?
If you need more information or my error description isnt clear dont hesitate to ask.
UPDATE:
how it should be:
behavior when the text is too long:
and a scrollbar appears on the bottom..

If you are trying to access a WPF object by name it needs to have x:Key="name" which wasn't shown in your code above, i.e.
<Window x:Name="MainWindow" ....
Alternatively you can walk back up the tree until you find an object of the correct type,
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}, Path=ActualWidth}"

Alternatively you can simply change the way you show the text to constrain its width
<ListBox Height="300" ItemsSource="{Binding Sites.View}" DisplayMemberPath="Name.ActualTranslation">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="Wrap" MaxWidth="200"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

WPF ListView shrink contents to fit container

I have a ListView that displays x items. It's defined like so;
<UserControl>
<UserControl.Resources>
<DataTemplate x:Key="MyCard" DataType="models:MyModel">
<StackPanel Background="{Binding BackgroundColour}"
Orientation="Vertical">
<Image Source="{Binding ImageSource}"
Stretch="Uniform"/>
<Label Content="{Binding MyType, Converter={StaticResource EnumDisplayNameConverter}}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ListView ItemsSource="{x:Static myNamespace:MyViewModel.Options}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemTemplate="{StaticResource MyCard}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</UserControl>
Unfortunately, the items still flow off the viewable area and get clipped, like so;
I was expecting that the items would resize to fit the bounds, but this is obviously not the case. I've tried adding a ViewBox to the DataTemplate to resolve this but it's still not working as expected.
The images are all 300px x 300px and I've tried setting MaxWidth/MaxHeight on the StackPanel, ViewBox and Image but it still flows off the "end".
Any suggestions on how I can resolve this?
Inside inner template, do not use StackPanel as it's growing bounds automatically to accommodate content (and would overlap ListBox scrollable area as well). If you expect auto-resizing, use Grid instead or set exact sizes on inner controls like Image etc.

How to use Textwrap property without defining the width in windows phone development?

I am using a grid with single row. I have placed a single LongListSelector within that row. The ItemTemplate is as follows,
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<!--when we dont mention any of the height and width properties then control tries to first occupy the minimum height/width required and then it streches to the extent it is possible-->
<phone:LongListSelector Grid.Row="0" x:Name="CLASS1">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="25,20" Background="#FF616464" Width="Auto">
<TextBlock Text="{Binding title, Mode=TwoWay}" FontSize="40" Margin="20,20" Foreground="White" TextAlignment="Left" TextWrapping="Wrap" FontStyle="Normal" FontFamily="Segoe UI"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
Now I know that if we don't mention the width,MaxWidth values in the XAML file or in the properties, the Textblock above will stretch itself to the width it really needs to fit in the text. If there still some more width remaining it will expand till that extent. However I want to wrap the text of the Textblock. At the same time I want to utilize all the width available for stretching the TextBlock. So basically I want that the Textblock to stretch itself using the maximum width available and if the Text within it is still longer then I want to wrap it. Is there any solution to achieve this. I can use text wrap by setting constant value for width. As I want to deploy this application on different models then can I make it generic? Is there anyway to use parent's width?
All you have to do is to replace StackPanel with Grid.
<DataTemplate>
<Grid Margin="25,20" Background="#FF616464" Width="Auto">
<TextBlock Text="{Binding title, Mode=TwoWay}" FontSize="40" Margin="20,20" Foreground="White" TextAlignment="Left" TextWrapping="Wrap" FontStyle="Normal" FontFamily="Segoe UI"/>
</Grid>
</DataTemplate>
Result:
try this property
HorizontalContentAlignment="Stretch"

How do I wrap content in a WPF ListView?

I have a very simple WPF ListView that I'm using to list blocks of text. I'd like it to scroll vertically, but the text should wrap so that there is no horizontal scroll. All the examples I've seen are overly convoluted DataGridView nesting solutions. This seems like such a simple use-case, however. Here is my current code:
<ListView
Height="Auto"
Width="Auto"
Margin="0"
Name="mLogListView"
FontWeight="Bold"
FontSize="16"
SelectionMode="Single"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch"/>
I've tried setting the ScrollViewer.HorizontalScrollBarVisibility and HorizontalContentAlignment properties but the text simply runs off the end of the control and doesn't wrap.
Each item is added to the ListView.Items collection and is a ListViewItem object. The text is set to the item's Content property.
Here is the code responsible for adding text times to the list:
ListViewItem item = new ListViewItem();
item.Content = "Item text is set here, but refuses to wrap in list view!";
mLogListView.Items.Add(item);
Thank you.
This should be what you need
<ListView Margin="12,23,309,191"
Name="mLogListView"
FontWeight="Bold"
FontSize="16"
SelectionMode="Single"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch" >
<!-- here set the itemTemplate to a TextBlock that can wraps-->
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.}" TextWrapping="Wrap"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Note the syntax Text="{Binding Path=.}" that is equivalent to Text="{Binding}". This is called empty binding syntax.
In this case Text is bound to the entire ListViewItem object. The empty binding syntax is useful when you want to bind to the entire object item instead of just to single property of the item.
This is convenient for the example because the source object (the ListViewItem) is of type string and you simply want to bind to the string itself.
For more information see msdn at section Specifying the Path to the Value
I wanted to view images in a ListView, it displays by default only one column. To prevent this, you can insert the following code:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="0" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
Now displays ListView, instead of one column, just one line :-(
To prevent this, you can insert this line of code:
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
So it could look something like this:
<ListView ItemsSource="{Binding YourItemsSource...}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border ... and so on ...
I hope, it can help someone
;-)

Silverlight 4 - simple control template

<DataTemplate x:Key="dirtSimple">
<TextBlock Margin="10,0,0,0" Text="{Binding Path=CurrentBook.Published, StringFormat=d}"></TextBlock>
</DataTemplate>
<ControlTemplate x:Key="lbWrapPanelTemplate">
<StackPanel Orientation="Horizontal" Margin="2" Background="Aqua">
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</ControlTemplate>
...
<ListBox Template="{StaticResource lbWrapPanelTemplate}" x:Name="bookListBox" Grid.Row="0" ItemsSource="{Binding Path=BookSource}" ItemTemplate="{StaticResource dirtSimple}" >
</ListBox>
The list box is displaying correctly, with a beautiful "Aqua" background, and each item is boringly displayed with just a date. For some reason though the items are not flowing horizontally. I originally tried it with the Silverlight Toolkit's WrapPanel, with the same problem, but I can't even get it to work with a built-in StackPanel, so I suspect I'm missing something.
Are you trying to get selection-based behavior that a ListBox provides? If not, use an ItemsControl (and supply an ItemsPanel as below).
The reason it's not going horizontal is the ItemsPresenter ultimately has its own panel it lays out items in. It's not inserting each item separately into your StackPanel (or WrapPanel), it's putting them in its own panel
What you want to do is specify a value for ItemsPanel like so:
<ListBox ItemTemplate="{StaticResource dirtSimple}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

Force TextBlock to wrap in WPF ListBox

I have a WPF listbox which displays messages. It contains an avatar on the left side and the username and message stacked vertically to the right of the avatar. The layout is fine until the message text should word wrap, but instead I get a horizontal scroll bar on the listbox.
I've Googled and found solutions to similar issues, but none of them worked.
<ListBox HorizontalContentAlignment="Stretch" ItemsSource="{Binding Path=FriendsTimeline}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border BorderBrush="DarkBlue" BorderThickness="3" CornerRadius="2" Margin="3" >
<Image Height="32" Width="32" Source="{Binding Path=User.ProfileImageUrl}"/>
</Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=User.UserName}"/>
<TextBlock Text="{Binding Path=Text}" TextWrapping="WrapWithOverflow"/> <!-- This is the textblock I'm having issues with. -->
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Contents of the TextBlock can be wrapped using property TextWrapping.
Instead of StackPanel, use DockPanel/Grid.
One more thing - set ScrollViewer.HorizontalScrollBarVisibility property to Disabled value for the ListBox.
Updated Hidden to Disabled based on comment from Matt. Thanks Matt.
The problem might not be located in the ListBox. The TextBlock won't wrap, if one of the parent controls provides enough space, so that it hasn't the need to wrap. This might be caused by a ScrollViewer control.
If you want to prevent TextBlock to grow, and you want it to just fit in the size of the listbox, you should set the width of it explicitly.
In order to change it dynamically, it means not a fix value, but you need to bind it to its proper parent element in the visual tree. You can have something like this:
<ListBox ItemsSource="{Binding MyItems}" Name="MyListBox">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Width"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ScrollContentPresenter}, Path=ActualWidth}" />
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If it does not work, try to find the proper elements (which has to be binded to what) with the Live Visual Tree in Visual Studio.

Resources