水平虚线拉伸到容器宽度

时间:2013-05-15 09:39:36

标签: wpf layout line

我有一个包含在ScrollViewer中的布局,我需要在其中绘制一条水平虚线,该虚线延伸到容器的整个宽度。我管理的最接近的是以下

<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

这个几乎可以工作,但是一旦容器(在我的情况下是一个窗口)被放大,当容器的尺寸向下缩小时,该线不会缩小回适当的尺寸。在我上下水平调整窗口大小之后,下面是同一窗口的屏幕截图。

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

请注意,这条线是虚线的这一事实很重要,因为这意味着涉及拉伸线的解决方案不起作用(破折号显示为拉伸)。

我知道这是因为X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"绑定(按照设计,行总是可滚动区域中最宽的东西,因此当我向下调整可滚动区域的窗口时,该行定义了可滚动的宽度但是我想不出解决办法。

如何解决此问题?


使用ViewportWidth无效的原因截图

Screenshot of why using ViewportWidth doesn't work

2 个答案:

答案 0 :(得分:9)

我意识到我需要的是Linelayout的测量步骤中要求零空间,但是在排列步骤中耗尽所有可用空间。我偶然遇到问题Make WPF/SL grid ignore a child element when determining size,它引入了使用包含此逻辑的自定义装饰器的方法。

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);
    }        
}

(我希望一些现有的布局控件包含这个逻辑,以避免编写我自己的布局逻辑,但是这里的逻辑非常简单,以至于我并不是真的那么烦恼)。然后修改后的XAML变为

<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>

这完美无缺

答案 1 :(得分:5)

您可以在左对齐的画布中放置一条非常长的行,将WidthClipToBounds设置为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>