如何在 VisualBrush 上设置 ViewPort 和 ViewBox 以在 WPF Canvas 中创建虚线背景?
How to set ViewPort and ViewBox on a VisualBrush to create a dotted background in a WPF Canvas?
我想创建一个带有对齐网格的 Canvas
。我实现了将我的对象捕捉到视图模型中的 20 像素网格的逻辑,现在我正在处理视图。我希望网格看起来像这样:
我想到了这个解决方案,但我不喜欢它,似乎有点乱(它使用 4 个对象而不是 1 个对象作为模式,这会影响性能吗?)。
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="-1,-1"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
问题是,如果我只使用一个 Ellipse
,没有像这样的负边距:
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
椭圆中心点偏移1px:
如果我添加 -1px 偏移量:
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
3/4 的点在背景图块之外:
我想我可以把点放在网格的中间,但是我必须更改我的视图模型计算并添加一个偏移量 - 我认为它比第一个视图更大 "hack"。
我怀疑应该有一些使用 ViewPort
和 ViewBox
的解决方法,但我还不太了解它们。
请给我最简单的解决方案,将我的背景设置为点捕捉网格,在 20px 网格中有点,没有偏移。 (例如,点以 (0,0) (0,20) (20,0) (20,20) 等为中心)
编辑:这应该足以重现矩形和控件:
<Canvas>
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1" />
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="-1,-1"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
<Canvas.Children>
<Rectangle Canvas.Left="40" Canvas.Top="40" Width="100" Height="80" Fill="Yellow" Stroke="blue" />
</Canvas.Children>
</Canvas>
将您的 Viewport
和 Viewbox
都设置为 -1 -1 20 20"
。它将显示如下:
ViewBox
表示你想取VisualBrush
的哪一部分,所以你必须从-1 -1
开始,否则你拿不到左上角的部分因为你的负面圈子 Margin
.
ViewPort
表示第一个图块在 Canvas
背景中的位置。同样,您希望它在 -1 -1
处将圆心与 Canvas
.
的原点对齐
对于简单的绘图,最好使用 DrawingBrush 而不是 VisualBrush:
<DrawingBrush TileMode="Tile"
Viewport="-10,-10,20,20" ViewportUnits="Absolute"
Viewbox="-10,-10,20,20" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="1" RadiusY="1"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
我想创建一个带有对齐网格的 Canvas
。我实现了将我的对象捕捉到视图模型中的 20 像素网格的逻辑,现在我正在处理视图。我希望网格看起来像这样:
我想到了这个解决方案,但我不喜欢它,似乎有点乱(它使用 4 个对象而不是 1 个对象作为模式,这会影响性能吗?)。
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="-1,-1"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
问题是,如果我只使用一个 Ellipse
,没有像这样的负边距:
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
椭圆中心点偏移1px:
如果我添加 -1px 偏移量:
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
3/4 的点在背景图块之外:
我想我可以把点放在网格的中间,但是我必须更改我的视图模型计算并添加一个偏移量 - 我认为它比第一个视图更大 "hack"。
我怀疑应该有一些使用 ViewPort
和 ViewBox
的解决方法,但我还不太了解它们。
请给我最简单的解决方案,将我的背景设置为点捕捉网格,在 20px 网格中有点,没有偏移。 (例如,点以 (0,0) (0,20) (20,0) (20,20) 等为中心)
编辑:这应该足以重现矩形和控件:
<Canvas>
<Canvas.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute" Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-1,-1" />
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-1,-1"/>
<Ellipse Height="2" Width="2" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="-1,-1"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
<Canvas.Children>
<Rectangle Canvas.Left="40" Canvas.Top="40" Width="100" Height="80" Fill="Yellow" Stroke="blue" />
</Canvas.Children>
</Canvas>
将您的 Viewport
和 Viewbox
都设置为 -1 -1 20 20"
。它将显示如下:
ViewBox
表示你想取VisualBrush
的哪一部分,所以你必须从-1 -1
开始,否则你拿不到左上角的部分因为你的负面圈子 Margin
.
ViewPort
表示第一个图块在 Canvas
背景中的位置。同样,您希望它在 -1 -1
处将圆心与 Canvas
.
对于简单的绘图,最好使用 DrawingBrush 而不是 VisualBrush:
<DrawingBrush TileMode="Tile"
Viewport="-10,-10,20,20" ViewportUnits="Absolute"
Viewbox="-10,-10,20,20" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="1" RadiusY="1"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>