简体   繁体   English

仅平铺图像时如何有效使用DrawingGroup?

[英]How can I use DrawingGroup effectively when tiling only images?

I'm having trouble understanding my problem with drawing groups. 我无法理解绘图组的问题。 I'm creating a map editor in wpf which is my first wpf project and I have been searching/playing around with drawing groups. 我正在wpf中创建一个地图编辑器,这是我的第一个wpf项目,并且我一直在搜索/使用图形组。

I have a set of tiles on the left side that on app startup populate based off of a folder of sprites. 我在左侧有一组磁贴,这些磁贴在应用程序启动时根据精灵文件夹填充。 They all layout according to rules I have set(3 sets of tiles per row at 32 pixels each). 它们都按照我设置的规则进行布局(每行3组图块,每组32个像素)。 Example below: 下面的例子:

    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;
    }

Now I Image control in another canvas which I want to do the same exact thing with exception that the tiles are placed dynamically. 现在,我在另一个画布中进行图像控制,除了平铺是动态放置的以外,我想做同样的事情。 Here is what I have so far: 这是我到目前为止的内容:

    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);

        }
    }

And here is the initialization of what uses areaDrawGroup: 这是使用areaDrawGroup的初始化:

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

If I do not add in a dead image located at point(0, 0) in the draw group and I click on the image control. 如果我没有添加位于绘图组中点(0,0)的无效图像,则单击图像控件。 It will offset to a weird location. 它将偏移到一个奇怪的位置。 As I continue to click more towards the top left location it correct where it draws the tile while shifting all the other ones over. 当我继续向左上方单击更多位置时,它会纠正绘制图块的位置,同时将所有其他图块移开。

My question is where could I find a good tiling example or what have I done wrong? 我的问题是我在哪里可以找到一个好的平铺示例,或者我做错了什么? Because adding in a dead image to fix where other images locate seems like a really bad hack to something simple I missed. 因为添加一个无效的图像以修复其他图像的位置对于我错过的简单操作来说似乎是一个非常糟糕的hack。

Here is what I did to solve this for now. 这是我目前为解决此问题所做的工作。 I have a i7 and used a list of drawingvisuals. 我有一个i7,并使用了一系列列表。 Don't have a problem with it. 没问题。 I thought at one point I should use one drawing visual and add each image to the same visual. 我认为我应该只使用一个绘图视觉效果,并将每个图像添加到同一视觉效果。 The problem with that is if I add a tile I have to re-open the render and redo all the drawing. 问题是如果我添加了一个图块,我必须重新打开渲染并重做所有图形。 Since I don't have any hiccups I decided not to use my time on that method. 由于我没有任何打ic,因此决定不花时间在那种方法上。

Here is code to copy and paste: 这是要复制和粘贴的代码:

  1. Make a class that derives framework element and add in the overrides as seen 创建一个派生框架元素的类,并添加覆盖

    public class AreaDrawingEdit : FrameworkElement { public VisualCollection Visuals { get; 公共类AreaDrawingEdit:FrameworkElement {public VisualCollection Visuals {get; set; 组; } const double COLLISION_OPACITY = 0.8; } 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. Add the framework element thing you made into your xaml file somewhere. 将您制作的框架元素添加到xaml文件中的某个位置。 lessthan local:AreaDrawingEdit Canvas.Left="0" Canvas.Top="0" OpacityMask="Black" x:Name="areaDrawingEdit" backslashgreaterthan 小于本地:AreaDrawingEdit Canvas.Left =“ 0” Canvas.Top =“ 0” OpacityMask =“ Black” x:Name =“ areaDrawingEdit” backslashgreaterthan

Enjoy the solution to my misery of figuring it out the hard-way. 享受我为解决这一难题而痛苦的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我怎样才能有效地使用 switch case 只向达到购买年龄的孩子展示某些电影? - How can I effectively use a switch case to only show certain movies to children who are of age to purchase them? 如何在Windows窗体上(有效)多线程? - How can I multithread (effectively) on Windows Forms? 如何有效地使用“使用”? - How to effectively use “using”? 如何有效使用数据透视? - How to use Pivot Effectively? C#如何更有效地使用NetworkStream? - C# How should I use NetworkStream more effectively? 如何测试DataContractSerializer是否被XmlProtoSerializer有效替换? - How can I test if the DataContractSerializer was effectively replaced by XmlProtoSerializer? 当只在运行时知道Type时,如何使用表达式树来调用泛型方法? - How can I use an expression tree to call a generic method when the Type is only known at runtime? 如何仅在程序集发生更改时才使用MSBuild更新版本信息? - How can I use MSBuild to update version information only when an assembly has changed? 如果存在平局,我如何指定使用Linq ThenBy子句? - How can I specify to use Linq ThenBy clause only when there is a tie? 如何在C#中使用图像作为切换按钮 - How can I use images for switch button in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM