[英]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: 这是要复制和粘贴的代码:
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]; }
} }
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.