wpf 水平虚线拉伸到容器宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16561639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:47:55  来源:igfitidea点击:

Horizontal dashed line stretched to container width

wpflayoutline

提问by Justin

I have a layout contained within a ScrollViewerin which I need to draw a horizontal dashed line that stretches to the full width of the container. The closest I've managed is the following

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

<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 nearlyworks, however once the container (in my case a window) has been enlarged, the line doesn't shrink back down to the appropriate size when the container is sized back down. The below is the screenshot of the same window after I have horizontally sized 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 that involve stretching the line don't work (the dashes appear stretched).

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

I know that this is because of the X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"binding (by design the line is always the widest thing in the scrollable region, so when I size the window down the scrollable region the line defines the width of the scrollable region), however I can't think of a solution.

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

How can I fix this problem?

我该如何解决这个问题?



Screenshot of why using ViewportWidthdoesn't work

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

Screenshot of why using ViewportWidth doesn't work

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

回答by Justin

I realised that what I needed was for the Lineto ask for zero space during the measure step of layout, but then use up all the available space during the arrange step. I happened to stumble across the question Make WPF/SL grid ignore a child element when determining sizewhich introduced the approach of using a custom decorator which included this logic.

我意识到我需要的是Line布局的测量步骤中要求零空间,然后在排列步骤中用完所有可用空间。我碰巧遇到了在确定大小时使 WPF/SL 网格忽略子元素的问题,该问题引入了使用包含此逻辑的自定义装饰器的方法。

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 layout control incorporated this logic to avoid having to write my own layout logic, however the logic here is so simple that I'm not really that fussed). The modified XAML then becomes

(我希望一些现有的布局控件包含此逻辑以避免必须编写我自己的布局逻辑,但是这里的逻辑非常简单,我并没有那么大惊小怪)。修改后的 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>

This works perfectly

这完美地工作

回答by Clemens

You may put a very long Line in a left-aligned Canvas with zero Widthand ClipToBoundsset to false.

您可以在左对齐的 Canvas 中放置一条很长的 LineWidthClipToBounds设置为0 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>