The meaning of my question changed after Anatoliy reminded me that CanContentScroll
does not enable or disable scrolling of content despite its name, but switches between scrolling by pixel and scrolling by item. However my intent was to stop scrolling behavior within a TextBox
altogether, and I have solved that problem now and also improved scrolling behavior in the ListBox
hosting them by eliminating the nested ScrollViewers:
First, I found this blog post which explains why ScrollViewer
always handles MouseWheel
. It is possible to subclass ScrollViewer to prevent this, which I was going to do until I wondered why I couldn't just change the content host element in the template to something without scrolling, since I don't need it at all. ContentPresenter
didn't work, but the Important Note Box on this MSDN page mentioned that TextBox only works with ScrollViewer
or AdornerDecorator
.
Switching to AdornerDecorator
worked perfectly:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
. . .
<AdornerDecorator x:Name="PART_ContentHost"
ClipToBounds="True"
Margin="{Binding GetTextOffset}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
I was able to bind the margin to my existing text offset property to position text as before, and ClipToBounds
confines the content to the visible area. The other major improvement is that scrolling through a collection of these TextBoxes in a ListBox
now works as expected since the textboxes aren't handing MouseWheel anymore. Nested ScrollViewers are unpleasant.