Обрезка WPF, даже если она не нужна - как ее отключить? - PullRequest
13 голосов
/ 01 февраля 2011

Мне нужно вывести некоторый контент из ListBox, как указано в DataTemplate для ListBox.ItemTemplate.Я использую RenderTransform, но содержимое обрезается по границам ListBox.ClipToBounds - это False для всего визуального дерева.

Я где-то читал, что WPF внутренне выполняет некоторое отсечение, даже если ни одно не указано с выделенными свойствами отсечения.Я также обнаружил, что использование Canvas иногда может решить проблему отсечения, но здесь это не помогает.

Как мне решить эту проблему?Вот некоторые XAML, которые я хочу исправить.Обратите внимание, что вся левая часть прямоугольника отсутствует.

    <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>

Ответы [ 2 ]

20 голосов
/ 01 февраля 2011

ListBoxItem обрезаются ScrollViewer в шаблоне ListBox.Чтобы обойти это, я думаю, вам нужно удалить ScrollViewer из шаблона и, если вам нужна прокрутка, вы можете обернуть ListBox в 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>

Обновление

ScrollViewer в шаблоне сгенерирует ScrollContentPresenter, который в свою очередь имеет следующий GetLayoutClip

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

Этот класс запечатан, поэтому вы не можете получить изэто переопределить этот метод.Вам придется реализовать свой собственный ScrollContentPresenter (например, MyScrollContentPresenter) и, вероятно, свой собственный ScrollViewer, который также использует MyScrollContentPresenter, чтобы сделать эту работу (и если вы вернете null в этом методе, я думаю, что некоторые элементыниже границ ListBox также может стать видимым)

0 голосов
/ 18 августа 2016

Я наткнулся на решение этой проблемы случайно, работая вокруг нее.Если вы измените ScrollViewer's HorizontalScrollMode и VerticalScrollMode на «Disabled» в шаблоне стиля, он прекратит отсечение в каждом направлении соответственно.

Редактировать: Может не работать для WPF.Я тестировал с приложением UWP.Рассматриваемые поля:

ScrollViewer.Hor HorizontalScrollMode = "Disabled"

ScrollViewer.VerticalScrollMode = "Disabled"

...