Horizontal dashed line stretched to the width of the container

I have a layout contained inside a ScrollViewer in which I need to draw a horizontal dashed line that extends to the full width of the container. The closest I managed is the following

 <ScrollViewer HorizontalScrollBarVisibility="Auto"> <StackPanel> <Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" /> <Line HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black" X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" StrokeDashArray="2 2" StrokeThickness="1" /> </StackPanel> </ScrollViewer> 

Sample looking good

This almost works, however, as soon as the container (in my case the window) is enlarged, the line will not be reduced to the desired size when the size of the container decreases. Below is a screenshot in the same window, after the horizontal size of the window up and down.

Screenshot of the sample after increasing and reducing the size of the window

Note that the fact that the line is dashed is important, as it means that solutions related to line stretching do not work (strokes appear stretched).

I know that this is due to the binding X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" (by design, the line is always the widest in the scroll area, so when I change the window down the scroll area, the line determines the width of the scrollable area ), however, I cannot come up with a solution.

How can I fix this problem?


Screenshot of why using ViewportWidth doesn't work

Screenshot of why using ViewportWidth doesn't work

+4
source share
2 answers

I realized that I needed Line request zero space during the layout measurement step, but then use close all available space during the arrangement step. I was fortunate enough to stumble over the question of Making the WPF / SL grid ignore the child when sizing , which introduced the approach of using a custom decorator that turned on this logic.

 public class NoSizeDecorator : Decorator { protected override Size MeasureOverride(Size constraint) { // Ask for no space Child.Measure(new Size(0,0)); return new Size(0, 0); } } 

(I was hoping that some existing control over the layouts enabled this logic to avoid the need to write my own layout logic, however the logic here is so simple that I really didn't fuss). Modified xaml then becomes

 <ScrollViewer HorizontalScrollBarVisibility="Auto"> <StackPanel> <Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" /> <local:NoSizeDecorator Height="1"> <Line Stroke="Black" HorizontalAlignment="Stretch" X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" StrokeDashArray="2 2" StrokeThickness="1" /> </local:NoSizeDecorator> </StackPanel> </ScrollViewer> 

It works great

+7
source

You can put a very long line in the left-aligned canvas with a Width zero and ClipToBounds set to false .

 <ScrollViewer HorizontalScrollBarVisibility="Auto"> <StackPanel> <Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" /> <Canvas HorizontalAlignment="Left" Width="0" ClipToBounds="False"> <Line Stroke="Black" StrokeDashArray="2 2" X2="10000"/> </Canvas> </StackPanel> </ScrollViewer> 
+3
source

Source: https://habr.com/ru/post/1480899/


All Articles