C# WPF нарисовать сетку сверху изображения

введите сюда описание изображения

На screenshot'e дизайнер VisualStudio, у меня есть Canvas и ImageBrush (Background), я с помощю DrawingBrush нашел пример рисования сетки на чистом Canvas

<DrawingBrush TileMode="Tile" Viewport="-10,-10,40,40" ViewportUnits="Absolute">
  <DrawingBrush.Drawing>
       <GeometryDrawing>                 
          <GeometryDrawing.Geometry>
             <RectangleGeometry Rect="0,0,50,50"/>
          </GeometryDrawing.Geometry>
          <GeometryDrawing.Pen>
             <Pen Brush="Gray" Thickness="1"/>
          </GeometryDrawing.Pen>
       </GeometryDrawing>
    </DrawingBrush.Drawing>
 </DrawingBrush>

но как нарисовать сетку сверху ImageBrush (изображения) как на скриншоте?


Ответы (1 шт):

Автор решения: return

По-быстрому склацал:

Controls/Lattice.cs

public class Lattice : Control
{
    public static readonly DependencyProperty RodPenProperty;

    public Pen? RodPen
    {
        get => GetValue(RodPenProperty) as Pen;
        set => SetValue(RodPenProperty, value);
    }

    static Lattice()
    {
        RodPenProperty = DependencyProperty.Register(
            "RodPen",
            typeof(Pen),
            typeof(Lattice));
    }

    protected override void OnRender(DrawingContext context)
    {
        const double maxCellSide = 50.0; // длина стороны 1-й клетки
        const int splitCnt = 2; // кол-во клеток, на которое будет производиться деление
        const double splitTreshold = 6.0; // порог расщепления (так просто не объяснить)

        if (!(Background is null)) context.DrawRectangle(Background, null!, new Rect(default, RenderSize));

        if (RodPen is null) return;

        var side = Math.Max(ActualWidth, ActualHeight);
        var cellSide = side / splitTreshold;

        for (; cellSide >= maxCellSide; cellSide /= splitCnt) { }

        var horRodCnt = (int)(ActualWidth / cellSide) + 1;
        var verRodCnt = (int)(ActualHeight / cellSide) + 1;

        for (var i = 1; i < horRodCnt; i++)
        {
            var offsetX = i * cellSide;

            context.DrawLine(RodPen, new Point(offsetX, 0), new Point(offsetX, ActualHeight));
        }
        for (var i = 1; i < verRodCnt; i++)
        {
            var offsetY = i * cellSide;

            context.DrawLine(RodPen, new Point(0, offsetY), new Point(ActualWidth, offsetY));
        }
    }
}

Примечание: константы заменить на свойства зависимостей.

MainWindow.xaml

<Window x:Class="RootNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RootNamespace"
        xmlns:ctrl="clr-namespace:RootNamespace.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ctrl:Lattice>
            <ctrl:Lattice.RodPen>
                <Pen Thickness="1" Brush="Gray"/>
            </ctrl:Lattice.RodPen>
        </ctrl:Lattice>
    </Grid>
</Window>

Меняйте размер окна: получаете иллюзию бесконечной сетки. Маштабирование – это и есть изменение размера (конечно, относительное).


Я думал, как реализовать это с помощью ImageBrush, но так и не придумал. Думаю, тут стоит использовать VisualBrush.

→ Ссылка