Ограничение WPF, даже если оно не требуется - как его отключить?
Мне нужно выложить некоторый контент из 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 ответа
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
может стать заметным)
Я наткнулся на решение этой проблемы случайно, работая вокруг нее. Если вы измените ScrollViewer's HorizontalScrollMode и VerticalScrollMode на "Disabled" в шаблоне стиля, он прекратит отсечение в каждом направлении соответственно.
Изменить: Может не работать для WPF. Я тестировал с приложением UWP. Рассматриваемые поля:
ScrollViewer.HorizontalScrollMode = "Выключено"
ScrollViewer.VerticalScrollMode = "Выключено"