I have a grid with some data and one of the cells contains rather long strings (and there could be quite a few). So to not use too much of the available window space, I'd like those strings to be scrollable. Vertically works, but whatever I try, I can't get a horizontal scrollbar.
This is my xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="250">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Grid.Column="0">
<ItemsControl ItemsSource="{Binding Path=BoundTexts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Text}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
and here's the code behind to test.
using System.Collections.Generic;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<BoundClass> temp = new List<BoundClass>();
for (int i = 0; i < 10; i++)
{
string t = ""; // just to create some long strings.
for (int j = 0; j < 10; j++) // I know it can be done better.
{
t += $"{j*10:D2}********";
}
temp.Add(new BoundClass(t));
}
BoundTexts = temp.ToArray();
DataContext = this;
}
public BoundClass[] BoundTexts { get; set; }
}
public class BoundClass
{
public string Text { get; set;}
public BoundClass(string text)
{
Text = text;
}
}
}
I know there are a few similar questions on here, but as far as I have seen, they are all shrouded in templates and other complex topics. Also some are answered by "make sure you have a restraining container around it", I think I do by the grid.
The proper way to add a
ScrollViewerto anItemsControlis to put it into theControlTemplateto wrap theItemsPresenter. This way theScrollViewerbehaves correctly.If you don't do it this way (and instead wrap the
ItemsControl) theScrollViewerwill try to scroll theItemsControland not the items!But you want the
ScrollViewerto detect when items of theItemsControloverflow. Naturally, theItemsControlitself will stretch to occupy the available space - it won't overflow and will be displayed correctly (fully visible). But the items do overflow the space of theItemsControl. That's why wrapping theItemsControlwon't work as expected.Additionally, you must explicitly enable the
ScrollViewer.HorizontalScrollBarVisibility. It's important to know that setting it toAutowill impact the performance. It's recommended to set it toHiddenorVisible.