#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. Фантастика. Спасибо! Ты избавляешь меня от лишней сердечной боли. Это действительно маленький раздражающий метод.