9

我有一个包含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>

样品看起来不错

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

增加和减小窗口大小后的示例截图

请注意,线是虚线这一事实很重要,因为这意味着涉及拉伸线的解决方案不起作用(虚线似乎被拉伸)。

我知道这是因为X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"绑定(根据设计,这条线始终是可滚动区域中最宽的东西,所以当我将窗口缩小到可滚动区域时,这条线定义了可滚动区域的宽度),但是我不能想一个解决办法。

我该如何解决这个问题?


为什么使用ViewportWidth不起作用的屏幕截图

为什么使用 ViewportWidth 不起作用的屏幕截图

4

2 回答 2

11

我意识到我需要的是在layoutLine的 measure 步骤中要求零空间,然后在安排步骤期间用完所有可用空间。我碰巧偶然发现了Make WPF/SL grid 在确定大小时忽略子元素的问题,该问题引入了使用包含此逻辑的自定义装饰器的方法。

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>

这完美地工作

于 2013-05-15T10:27:32.770 回答
8

您可以将一条很长的 Line 放在左对齐的 Canvas 中,为零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>
于 2013-05-15T10:25:22.527 回答