Почему мои панели обрезаются по всему периметру панели, если они меньше заданного размера?

Вероятно, запутанный заголовок вопроса.

Сетка с красным прямоугольником — пример того, как это должно выглядеть.

Сетка с синим прямоугольником (не показанная на изображении) имеет поле, которое заставляет вторую сетку быть меньше, чем я явно установил ее. Что, по-видимому, заставляет WPF переворачиваться и скрывать все, что находится за пределами его установленных границ.

введите здесь описание изображения

Я попытался установить клип, чтобы он был больше, чем сетка.

Единственный способ избежать этого — написать пользовательскую панель, которая измеряет свои дочерние элементы с ограничением PositiveInfinity, но затем упорядочивает дочерние элементы с правильной шириной. У этого метода много проблем. Нехорошо лгать своим детям.

В любом случае, вот код:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="NegativeMarginTooMuchClipping.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="400">

<Grid>
    <StackPanel Width="600" Height="300">
    <Grid Margin="40,50,60,50" Background="#FFB8B8B8" Width="500" Height="50">
        <Rectangle Fill="Red" HorizontalAlignment="Left" Height="50" VerticalAlignment="Top" Width="50" Margin="0,-50,0,0"/>
    </Grid>
    <Grid Margin="40,50,61,50" Background="#FFB8B8B8" Width="500" Height="50">
        <Rectangle Fill="Blue" HorizontalAlignment="Left" Height="50" VerticalAlignment="Top" Width="50" Margin="0,-50,0,0"/>
    </Grid>
    </StackPanel>
</Grid>

Known issue? Am I doing it wrong? Need more clarification?


person chrislarson    schedule 27.04.2011    source источник
comment
Сначала вы перемещаете синий прямоугольник за пределы сетки, а затем даже перемещаете его через границы StackPanel, синий прямоугольник не удивлен.   -  person H.B.    schedule 28.04.2011


Ответы (1)


Есть три вещи, которые влияют на определение того, как что-то клипируется. Первые два — это ClipToBounds и Clip, но третья немного более раздражает и это GetLayoutClip.

По умолчанию для UIElement метод GetLayoutClip возвращает либо null, либо RectangleGeometry того же размера, что и элемент, в зависимости от свойства ClipToBounds. Однако FrameworkElement и его производные гораздо сложнее. Посмотрите в Reflector/ILSpy, и вы поймете, что я имею в виду.

Однако вы можете переопределить это поведение. Если вы используете что-то вроде следующего в качестве сетки для синего прямоугольника, он больше не будет обрезан:

public class MyGrid : Grid {
    protected override Geometry GetLayoutClip(Size layoutSlotSize) {
        return null;
    }
}

здесь есть отличная запись в блоге.

person CodeNaked    schedule 27.04.2011
comment
Фантастический. Спасибо! Ты спасаешь меня от сердечной боли. Это действительно раздражающий маленький метод. - person chrislarson; 28.04.2011