当我只平铺图像时,如何有效地使用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,我错过了一些简单的东西。
这是我现在解决这个问题的方法。我有一个i7,并使用了一个绘图视觉列表。别有意见。我一度认为我应该使用一个绘图视觉,并将每个图像添加到相同的视觉中。问题是,如果我添加一个瓷砖,我必须重新打开渲染和重做所有的绘图。既然我没有打嗝,我决定不把时间花在那个方法上。
下面是复制粘贴的代码:创建一个类,派生框架元素并添加覆盖,如
所示公共类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]; }
}
将框架元素添加到xaml文件的某个地方。less local:AreaDrawingEdit Canvas。左= " 0 "画布。Top="0" OpacityMask="Black" x:Name="areaDrawingEdit" backslashgreaterthan
享受解决我的痛苦的艰难的方法。