保留直线的LineCap属性,同时填充缺失的角

时间:2019-05-30 10:43:03

标签: wpf line cap

我目前正在尝试使用给定的坐标来模拟铁路的轨迹。以前,我一直在为StrokeStart和StrokeEnd LineCap属性使用'Rounded'值,但是使用该值获得的附加半径在添加轨道接头时会引起问题。我将LineCap的值设置为“ flat”,除了没有填充轨迹的“角”这一事实以外,它的效果要好得多:

缺少角点 https://imgur.com/a/EliIlzD

我试图通过以下方法来抵消这种情况:首先用“ Round”值渲染我的所有轨迹,然后再用“ Flat”值再次渲染它们的顶部,该值似乎填满了角落,但导致其他问题,例如,在占用轨道时颜色会重叠,而我首先渲染的圆形轨道会在轨道末端出现:

重叠的颜色 https://imgur.com/a/0XCVGv5

曲目结尾处的问题 https://imgur.com/a/fKju9uA

我的XAML只是一条简单的线,它是由视图列表中形成的坐标列表构成的,这些坐标具有来自我的视图模型的各种绑定,并且转换器可以将坐标稍微缩小一些。显然,这是首先使用Rounded EndCaps渲染的轨道:


<Line  X1="{Binding X1, Converter={StaticResource ScaleXCoordConverter}}" Y1="{Binding Y1, Converter={StaticResource ScaleYCoordConverter}}"
                                                   X2="{Binding X2, Converter={StaticResource ScaleXCoordConverter}}" Y2="{Binding Y2, Converter={StaticResource ScaleYCoordConverter}}"
                                                   Stroke="{Binding DataContext.LineColor, RelativeSource={RelativeSource AncestorType=ContentPresenter, AncestorLevel=2}}" 
                                                   StrokeThickness="2" StrokeEndLineCap="Round" StrokeStartLineCap="Round">
                                                <Line.InputBindings>
                                                    <MouseBinding Gesture="LeftClick" Command="{Binding DataContext.OccupyTrackCommand, RelativeSource={RelativeSource AncestorType=ContentPresenter, AncestorLevel=2}}"/>
                                                </Line.InputBindings>

                                            </Line>

是否有人幸运地创建了解决这些问题的自定义线,您可以在其中使用LineCap的“ Flat”值,而不会出现任何问题地保留拐角?编辑:只是为了澄清一下,我想我要求自定义实现的行或行上限来解决所有这些问题,但是任何其他解决方案都非常受欢迎。

1 个答案:

答案 0 :(得分:0)

我想出的解决方案是针对我的项目的,但是我认为无论如何我都会发布它,以防将来遇到这个问题的任何人都受益。

private void SetLineCaps() {

        if (LineCoords.Count == 1) {
            LineCoords[0].StartLineCap = "Flat";
            LineCoords[0].EndLineCap = "Flat";
            return;
        }
        foreach (var currentCoord in LineCoords) {
            foreach (var compareCoord in LineCoords) {


                if(currentCoord == compareCoord) continue;
                if ((compareCoord.X1 == currentCoord.X1 && compareCoord.Y1 == currentCoord.Y1)
                    || (compareCoord.X2 == currentCoord.X1 && compareCoord.Y2 == currentCoord.Y1)) {
                    currentCoord.StartLineCap = "Round";
                }
                if ((compareCoord.X1 == currentCoord.X2 && compareCoord.Y1 == currentCoord.Y2 )
                    || (compareCoord.X2 == currentCoord.X2 && compareCoord.Y2 == currentCoord.Y2)){ 

                    currentCoord.EndLineCap = "Round";
                }
            }
        }
    }

基本上,我最终要做的是检查每行的起点和终点,并检查起点或终点是否触及该特定行列表的任何其他点。例如,如果我有一条包含3条线的轨道,它将检查是否有任何线端在接触,如果有,则将特定的线帽设置为“ Round”,否则将其保持为“ Flat”。然后,我将StartLineCap和EndLineCap限制为这些值,并且一切正常。如果您希望了解我如何处理流血的颜色,请参阅其他有关z-index的文章。