En primer lugar, creo que es necesario dar más detalles sobre cuáles son tus limitaciones y lo que estamos tratando de lograr. Sin eso, solo puedo explicar por qué lo que estás haciendo no está funcionando. Alguien puede incluso tener una mejor idea acerca de cómo obtener el resultado que busca.
Si coloca dentro de un ListBox
ScrollViewer
, entonces el control template para ListBox
todavía tiene su propia ScrollViewer
interior. Cuando el cursor del mouse está sobre el ListBox
y se desplaza la rueda del mouse, ese evento aparece hasta que llega al ScrollViewer
que forma parte de ListBox
. Eso lo maneja desplazándose y marca el evento como manejado, entonces el ScrollViewer
en el que coloca el ListBox
ignora el evento.
Si usted hace la ListBox
más alto y más estrecho que el exterior ScrollViewer
, y darle suficientes elementos para que el ListBox
sí mismo puede desplazarse los artículos, verá 2 barras de desplazamiento vertical: 1 en el ListBox
y 1 fuera de la ListBox
para su exterior ScrollViewer
. Cuando el cursor del mouse esté dentro del ListBox
, el ListBox
desplazará los elementos con su ScrollViewer
interno, y su Border
permanecerá en su lugar. Cuando el cursor del mouse está fuera del ListBox
y dentro del exterior ScrollViewer
, ese ScrollViewer
desplazará su contenido - ListBox
- que puede verificar al observar que ListBox
's Border
cambia de posición.
Si desea una combinación externa ScrollViewer
para desplazarse todo el ListBox
de control (incluyendo los Border
y no sólo los artículos), tendrá que volver al estilo de la ListBox
de modo que no tiene un interior ScrollViewer
, pero' También será necesario asegurarse de que aumente automáticamente de acuerdo con sus artículos.
No recomiendo este enfoque por un par de razones.Puede tener sentido si hay otros controles dentro del ScrollViewer
junto con el ListBox
, pero su muestra no lo indica. Además, si va a tener muchos elementos en el ListBox
, creará ListBoxItem
s para cada uno, eliminando cualquier ventaja que le brinde el ListBox
predeterminado, sin cambiar el estilo, debido al VirtualizingStackPanel
predeterminado.
Háganos saber cuáles son sus necesidades reales.
Editar: Ok, ahora tengo un poco mejor idea, con la adición de esas imágenes. El efecto que obtiene es que cuando hay suficientes elementos para desplazarse y aparece la barra de desplazamiento, el área disponible debe reducirse un poco horizontalmente porque la plantilla ScrollViewer
usa un Grid
. Estas parecen ser las opciones, con el fin de menor a mayor: Re-estilo
- la
ListBox
que no tienen una ScrollViewer
y usar su re-labrado ScrollViewer
fuera del ListBox
. También tendría que forzar el ListBox
para que también sea lo suficientemente alto como para mostrar todos los elementos en el mismo Style
, y ahora ha perdido la virtualización de la interfaz de usuario. Si va a mostrar cientos de artículos en la lista, usted definitivamente no quiere perder eso.
- Vuelva a diseñar el
ListBox
y configure ControlTemplate
para usar un ScrollViewer
con el estilo que ya creó para que coloque la barra de desplazamiento sobre el contenido en lugar de en una columna separada. Este está bien (ListBox
llega a limitar su altura y usa un VirtualizingStackPanel
, yay), pero como dijiste, necesita conocimiento de eso en tu DataTemplate
.
- Vuelva a diseñar el
ScrollViewer
para dejar espacio para la barra de desplazamiento vertical, incluso cuando no esté visible. Esto es lo que se ve esta opción como:
Por defecto, ScrollViewer
utiliza 2 columnas en un Grid
equivalente a esto:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
Así que la Width
de la columna de la barra de desplazamiento es 0 cuando la barra de desplazamiento no es visible desde Width="Auto"
. Para dejar espacio para la barra de desplazamiento, incluso cuando está oculto, nos atamos a la Width
de esa columna a la Width
de la barra de desplazamiento vertical:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
Así que ahora la ControlTemplate
en la costumbre Style
para ScrollViewer
podría tener este aspecto:
<ControlTemplate
TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter />
<ScrollBar
Grid.Column="1"
Name="PART_VerticalScrollBar"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
Usted podría incluso hacer la columna el contenido de un tamaño fijo y la columna de la barra de desplazamiento Width="*"
, lo que podría funcionar mejor en el largo plazo si su imagen no se estira. Ahora, el DataTemplate
no tiene que compensar el ancho de una barra de desplazamiento, ya que tiene un área consistente para usar si la barra de desplazamiento está visible o no.
Probablemente querrá ver el resto de example ControlTemplate
for ScrollViewer
, pero esos ejemplos no son los estilos predeterminados. ¡Observe que el ejemplo pone la barra de desplazamiento vertical a la izquierda! También tenga en cuenta el comentario al final sobre ContentScrollPresenter
.
Actualizado mi publicación .. –