Зачем вам нужно обернуть ListBox в ScrollViewer? ListBox автоматически отображает ScrollViewer, когда его содержимое не помещается в доступное пространство. Вы можете удалить его из XAML, и он все равно должен работать. По крайней мере, это для меня. :)
Я опробовал ваш ControlTemplate, и он, кажется, работал очень хорошо. Проблема заключается в том, что в то время как 3-й столбец изменяется до ширины ListBox, если текст в 3-м столбце очень длинный, 4-й столбец не будет отображаться, пока весь текст не станет видимым.
Я также попробовал другой метод компоновки, который не уверен насчет производительности, но идея заключалась в том, чтобы использовать DockPanel вместо Grid. Я добавил третий столбец последним в XAML, чтобы он заполнил оставшееся пространство, и закрепил его слева (я закрепил 4-й столбец справа). Было бы желательно отобразить всю строку в 3-м столбце. Я не знаю, почему это происходит, и почему текст не будет переноситься или использовать многоточие, когда свободного места недостаточно для отображения текста.
<Window.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<DockPanel Width="Auto">
<CheckBox Width="20" VerticalAlignment="Center" DockPanel.Dock="Left" IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}" />
<TextBlock Width="50" VerticalAlignment="Center" DockPanel.Dock="Left" Margin="5,0,5,0" Text="hi" />
<Button Width="30" HorizontalAlignment="Right" DockPanel.Dock="Right" Margin="5,0,5,0">-></Button>
<TextBlock VerticalAlignment="Center" DockPanel.Dock="Left" Margin="5,0,5,0" Text="afdjfksdhahjklfadshjlasffasdlhjsafdlhjasdfasfhdjlaslfhdjsfdhjlsfdlhjsfdhjsfdddsd" TextTrimming="CharacterEllipsis" TextWrapping="WrapWithOverflow" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>