当我只平铺图像时,如何有效地使用DrawingGroup ?

本文关键字:有效地 DrawingGroup 图像 | 更新日期: 2023-09-27 17:51:18

我很难理解我的问题与绘图组。我正在wpf中创建一个地图编辑器,这是我的第一个wpf项目,我一直在搜索/玩绘图组。

在应用启动时,我在左侧设置了一组基于精灵文件夹的贴图。它们都按照我设定的规则进行布局(每行3组贴图,每组32像素)。在下面的例子:

    private void RefreshTileList()
    {
        // For now load in all textures as possible tiles
        DrawingGroup dGroup = new DrawingGroup();
        Rect r = new Rect();
        r.X = 0.0;
        r.Y = 0.0;
        r.Width = Settings.Default.TileThumbWidth;
        r.Height = Settings.Default.TileThumbHeight;
        foreach (WPFTexture tex in imgFind.TileTextures)
        {
            ImageDrawing iDraw = new ImageDrawing(tex.src, r);
            dGroup.Children.Add(iDraw);
            r.X += r.Width;
            if (r.X > r.Width * Settings.Default.TileThumbMaxColumns)
            {
                r.X = 0.0;
                r.Y += r.Height;
            }
        }
        // Make a drawing image and send it to the Image in canvas
        DrawingImage drawImage = new DrawingImage(dGroup);
        tileImage.Source = drawImage;
    }

现在我的图像控制在另一个画布,我想做同样的事情,除了瓷砖是动态放置。以下是目前为止的内容:

    private void AreaDrawingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(curSelIndex > -1 && curSelIndex < imgFind.TileTextures.Count)
        {
            BitmapSource tileSrc = imgFind.TileTextures[curSelIndex].src;
            Point mousePos = e.GetPosition(sender as Canvas);
            Size size = new Size(tileSrc.Width, tileSrc.Height);
            Rect r = new Rect(mousePos, size);
            ImageDrawing iDraw = new ImageDrawing(tileSrc, r);
            areaDrawGroup.Children.Add(iDraw);
        }
    }

下面是使用areaDrawGroup的初始化:

        // Setup drawing for area
        DrawingImage areaDrawImage = new DrawingImage(areaDrawGroup);
        areaImage.Source = areaDrawImage;
        areaImage.Stretch = Stretch.None;
        AreaDrawingCanvas.Children.Add(areaImage);

如果我没有添加位于绘图组中点(0,0)的死图像,并且我单击图像控件。它会偏移到一个奇怪的位置。当我继续点击左上角的位置时,它会在移动所有其他位置的同时正确地绘制瓦片。

我的问题是我在哪里可以找到一个好的平铺例子,或者我做错了什么?因为添加一个死图像来修复其他图像的位置似乎是一个非常糟糕的hack,我错过了一些简单的东西。

当我只平铺图像时,如何有效地使用DrawingGroup ?

这是我现在解决这个问题的方法。我有一个i7,并使用了一个绘图视觉列表。别有意见。我一度认为我应该使用一个绘图视觉,并将每个图像添加到相同的视觉中。问题是,如果我添加一个瓷砖,我必须重新打开渲染和重做所有的绘图。既然我没有打嗝,我决定不把时间花在那个方法上。

下面是复制粘贴的代码:
  1. 创建一个类,派生框架元素并添加覆盖,如

    所示

    公共类AreaDrawingEdit: FrameworkElement{公共的VisualCollection视觉{获取;设置;}const double COLLISION_OPACITY = 0.8;

    public AreaDrawingEdit()
    {
        Visuals = new VisualCollection(this);
    }
    public void AddRenderTile(DrawingTile tile)
    {
        // Add the tile visual 
        tile.visual = new DrawingVisual();
        InvalidateTile(tile);
        Visuals.Add(tile.visual);
        // Add in collision visual
        tile.colVol.visual = new DrawingVisual();
        InvalidateCollisionVol(tile.colVol);
        Visuals.Add(tile.colVol.visual);
    }
    public void RemoveRenderTile(DrawingTile tile)
    {
        Visuals.Remove(tile.visual);
        Visuals.Remove(tile.colVol.visual);
    }
    public void InvalidateTile(DrawingTile tile)
    {
        // Set up drawing rect for new tile
        Rect r = new Rect(tile.pos, new Size(tile.tileTex.src.PixelWidth, tile.tileTex.src.PixelHeight));
        DrawingContext dc = tile.visual.RenderOpen();
        dc.DrawImage(tile.tileTex.src, r);
        dc.Close();
    }
    public void InvalidateCollisionVol(CollisionVol vol)
    {
        Rect r = new Rect(vol.pos, vol.size);
        DrawingContext dc = vol.visual.RenderOpen();
        dc.PushOpacity(COLLISION_OPACITY);
        dc.DrawImage(vol.src, r);
        dc.Pop();
        dc.Close();
    }
    protected override int VisualChildrenCount
    {
        get { return Visuals.Count; }
    }
    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= Visuals.Count)
        {
            throw new ArgumentOutOfRangeException();
        }
        return Visuals[index];
    }
    

    }

  2. 将框架元素添加到xaml文件的某个地方。less local:AreaDrawingEdit Canvas。左= " 0 "画布。Top="0" OpacityMask="Black" x:Name="areaDrawingEdit" backslashgreaterthan

享受解决我的痛苦的艰难的方法。