2011-01-31 11 views
13

Necesito que salga algo de contenido del ListBox como se especifica en un DataTemplate para un ListBox.ItemTemplate. Estoy usando RenderTransform pero el contenido se recorta en ListBox boundaries. ClipToBounds es False para todo el árbol visual.recorte de WPF incluso cuando no se desea ningún recorte, ¿cómo desactivarlo?

He leído en algún lugar que WPF realiza internamente algunos clipping incluso cuando no se especifica ninguno con propiedades de recorte dedicadas. También descubrí que usar Canvas a veces puede curar el problema de recorte, pero no ayuda aquí.

¿Cómo puedo solucionar este problema? Aquí hay algunos XAML que quiero arreglar. Tenga en cuenta que falta toda la parte izquierda del rectángulo.

<ListBox> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50"> 
        <Rectangle.RenderTransform> 
         <TranslateTransform X="-50" /> 
        </Rectangle.RenderTransform> 
       </Rectangle> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 

     42 
    </ListBox> 

Respuesta

19

Los ListBoxItem 's se están cortadas por el ScrollViewer en la plantilla ListBox. Para evitar esto, creo que necesita para eliminar el ScrollViewer de la plantilla y si es necesario el desplazamiento se puede envolver el ListBox en un ScrollViewer

<ScrollViewer HorizontalScrollBarVisibility="Auto" 
       VerticalScrollBarVisibility="Auto"> 
    <ListBox Margin="100,10,0,0"> 
     <ListBox.Template> 
      <ControlTemplate TargetType="{x:Type ListBox}"> 
       <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true"> 
        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsEnabled" Value="false"> 
         <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </ListBox.Template> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50"> 
        <Rectangle.RenderTransform> 
         <TranslateTransform X="-50" /> 
        </Rectangle.RenderTransform> 
       </Rectangle> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 42 
    </ListBox> 
</ScrollViewer> 

actualización

El ScrollViewer en la plantilla generar una ScrollContentPresenter que a su vez tiene la siguiente GetLayoutClip

protected override Geometry GetLayoutClip(Size layoutSlotSize) 
{ 
    return new RectangleGeometry(new Rect(base.RenderSize)); 
} 

Este cla ss está sellado por lo que no puede derivarse de él para anular este método. Tendría que implementar su propio ScrollContentPresenter (por ej. MyScrollContentPresenter) y probablemente su propio ScrollViewer que usa MyScrollContentPresenter para hacer que esto funcione (y si devuelve null en este método, creo que algunos elementos debajo de los límites del ListBox podrían hacerse visibles como bien)

+0

Usted parece ser el clavo! Pero necesito ese 'ScrollViewer' en su lugar original. ¿Sabes lo que es tan especial en la implementación interna de 'ScrollVeiwer' que me duele? ¿Es esto algo que puede ser anulado en una clase derivada? He leído en alguna parte que 'GetLayoutClip' es el culpable, pero no puedo hacer que funcione a mi manera. – wpfwannabe

+1

@wpfwannabe: Actualicé mi respuesta. Tienes razón en que 'GetLayoutClip' es el problema. Desafortunadamente, esta vez está en una clase Sellada ('ScrollContentPresenter') por lo que no puede derivarse de ella. Por lo que sé, tomaría mucho trabajo para que esto funcione –

+0

¡Su respuesta es excelente! ¡Gran ayuda! ¡Muchas gracias! Mientras tanto, he reorganizado mi diseño de forma diferente con una especie de 'ListBoxItem' dividido que me permite mostrar el contenido flotante dentro de 'ListBox' y, por lo tanto, ya no necesito toda esta malarkey' ScrollViewer'. La mayoría de las veces uno puede encontrar una solución diferente al mismo problema.Esta vez he tenido que cambiar bastante mis plantillas para hacer que las cosas funcionen como esperaba, pero parece ser mucho más fácil que tener que lidiar con la creación de mi propio 'ScrollViewer'. ¡Gracias de nuevo! – wpfwannabe

-2

Me encontré con una solución a este problema por accidente mientras trabajaba alrededor. Si cambia el HorizontalScrollMode y VerticalScrollMode de ScrollView a "Desactivado" dentro de la plantilla de estilo, se detendrá el recorte en cada dirección, respectivamente.

Editar: Puede que no funcione para WPF. Probé con una aplicación UWP. Los campos en cuestión son:

ScrollViewer.HorizontalScrollMode = "desactivada"

ScrollViewer.VerticalScrollMode = "desactivada"

+0

No existe ninguna propiedad como HorizontalScrollMode en WPF – Walkor

+0

Lo siento, debería haber mencionado, lo había probado y lo había funcionado en aplicaciones UWP, y había asumido que se aplicaría a WPF. Adivina sin embargo. –