代码之家  ›  专栏  ›  技术社区  ›  Joe White

在WPF中无缝平铺矩形

  •  6
  • Joe White  · 技术社区  · 16 年前

    我想在WPF中无缝地平铺一堆不同颜色的矩形。也就是说,我想把一堆长方形边到边,而不是它们之间有间隙。

    如果所有内容都与像素对齐,则工作正常。但我也希望支持任意缩放,而且理想情况下,我不想使用SnapsToDevicePixels(因为当图像被放大时会影响质量)。但这意味着我的矩形有时会有间隙。例如:

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Background="Black">
      <Canvas SnapsToDevicePixels="False">
        <Canvas.RenderTransform>
          <ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
        </Canvas.RenderTransform>
        <Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC"/>
        <Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF"/>
      </Canvas>
    </Page>
    

    如果ScaleTransform的ScaleX为1,则矩形将无缝地组合在一起。当0.5时,它们之间有一条深灰色的条纹。我明白为什么——组合的半透明边缘像素不能组合成100%不透明。但我想找个办法解决它。

    我总是可以让矩形重叠,但我并不总是提前知道它们会是什么模式(这是一个最终支持地图编辑器的游戏)。此外,当事情被放大时,这会导致重叠区域周围出现伪影 在里面 (除非我在底图部分做了斜角切割,这是一项非常繁重的工作,而且仍然会在拐角处造成问题)。

    有没有什么方法可以将这些矩形组合成一个没有内部间隙的组合“形状”?我玩过GeometryDrawing,它确实做到了这一点,但是我看不到用不同颜色的画笔来绘制每个矩形几何体的方法。

    有没有其他方法可以让形状在任意转换下无缝平铺,而不诉诸SnapsToDevicePixels?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Nicholas Armstrong    16 年前

    您可以考虑使用指导原则(请参见 GuidelineSet on MSDN )重写矩形的OnRender方法,使其边界与设备的像素边界对齐。WPF使用准则来确定是否以及在何处捕捉图形。

    可以 可以使用附加属性来执行此操作,以便可以将其应用于任何元素,但如果只需要对一种类型的元素(例如矩形)执行此操作,则可能不值得额外的努力。

    WPF 4.0 is expected to feature Layout Rounding ,其中, like the version in Silverlight ,当启用布局舍入时,舍入渲染过程中的非整数值。

        2
  •  0
  •   cauon    13 年前

    我想间隙不是实际的间隙,而是画出来的笔划。当你缩小它时,你只需要把笔划缩小到一个不再可见的点。我试着用矩形的颜色来画笔划,在任何尺度上都可以。

    &ltPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Background="Black"&gt
      &ltCanvas SnapsToDevicePixels="False"&gt
        &ltCanvas.RenderTransform&gt
          &ltScaleTransform ScaleX="0.5" ScaleY="0.5"/&gt
        &lt/Canvas.RenderTransform&gt
        &ltRectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC" Stroke="#CFC"/&gt
        &ltRectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF" Stroke="#CCF"/&gt
      &lt/Canvas&gt
    &lt/Page&gt