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

#wpf #layout #panel #margin #clipping

#wpf #макет #панель #margin #обрезка

Вопрос:

Вероятно, название вопроса сбивает с толку.

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

Сетка с синим прямоугольником (не отображается на изображении) имеет запас, который заставляет вторую сетку быть меньше, чем я явно установил. Что, по-видимому, приводит к тому, что 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>
  

Известная проблема? Я делаю это неправильно? Нужно больше разъяснений?

Комментарии:

1. Сначала вы перемещаете синий прямоугольник за пределы сетки, а затем вы даже перемещаете его через границы StackPanel, синий прямоугольник не забавляет.

Ответ №1:

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

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

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

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

Об этом Здесь есть отличный пост в блоге.

Комментарии:

1. Фантастика. Спасибо! Ты избавляешь меня от лишней сердечной боли. Это действительно маленький раздражающий метод.