Reputation: 1703
Here is my problem. I've built the following ListView
<ListView Grid.Row="1" x:Name="messageList" BorderThickness="0"
ItemsSource="{Binding MySource}"
HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<WrapPanel Grid.Row="0" Grid.Column="0">
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.SenderId}"
/>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.DeliverDate}"
/>
</WrapPanel>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.MsgText}"
Grid.Row="1" Grid.Column="0"
TextWrapping="WrapWithOverflow">
</TextBlock>
<WrapPanel Grid.Row="0" Grid.Column="1">
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.SenderId}"
/>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.DeliverDate}"
/>
</WrapPanel>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.MsgText}"
Grid.Row="1" Grid.Column="1"
TextWrapping="WrapWithOverflow">
</TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
For each element of MySource
only 1 between Received and Sent will be not null. The ListView
is working as i expect, placing the element on the left or the right of the screen, but the TextBlock
that contain the MsgText
get all the available space (so the whole row) if the message is too long. How can i limit it to stay only in one half of the parent Grid and make the text overflow eventually?
EDIT: I added an image showing my problem. The 4th message should overflow, but it doesn't
Upvotes: 0
Views: 258
Reputation: 21969
It took me few minutes to produce mcve, but the missing part of the puzzle is this:
<Grid MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}">
That would limit maximum width of all Grid
s (each item has one) and let wrapping happens. Otherwise Grid
is asking for a width to fit whole item in one line and ListView
is ok with it, but then you will see horizontal scrollbar (the most hated control by users including me).
MCVE:
public partial class MainWindow : Window
{
public class Item
{
public string Received { get; set; }
public string Sent { get; set; }
}
public List<Item> Items { get; }
public MainWindow()
{
InitializeComponent();
Items = new List<Item>
{
new Item { Received = "1111 111 11 111 11 1" },
new Item { Received = "2222 2 22 2 2 222222222 2 222222 22222222 222222222222 2" },
new Item { Sent = "333333333 3333333 333 33333 3 3 33 333333333 3333" },
new Item { Received = "444444444444444 444 44444444444444 44 4 44444444444444444 4 4 4444444444 4 444 444444444444" },
};
DataContext = this;
}
}
Screenshot:
Xaml:
<ListView ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Received}"
TextWrapping="WrapWithOverflow" />
<TextBlock Grid.Column="1"
Text="{Binding Sent}"
TextWrapping="WrapWithOverflow" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
Upvotes: 1
Reputation: 979
The problem is that your grid (and the width of the column) is calculated for each element of your list, so it takes the most space possible. I propose a backup solution, I did not find better but the result is there.
This is to place 2 ListView in 2 columns of a grid and then have the Received element in one and the Sent in the other.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" x:Name="messageListReceived" BorderThickness="0"
ItemsSource="{Binding MySource}"
HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0">
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.SenderId}"
/>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.DeliverDate}"
/>
</WrapPanel>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Received.MsgText}"
Grid.Row="1"
TextWrapping="WrapWithOverflow">
</TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Grid.Column="1" x:Name="messageListSent" BorderThickness="0"
ItemsSource="{Binding MySource}"
HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0">
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.SenderId}"
/>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.DeliverDate}"
/>
</WrapPanel>
<TextBlock Margin="2"
VerticalAlignment="Center"
Text="{Binding Sent.MsgText}"
Grid.Row="1"
TextWrapping="WrapWithOverflow">
</TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Upvotes: 0