使用GDI +在C#中绘制和填充矩形时遇到问题。我正在尝试渲染一个treemap,因此构建了一个递归算法,它从树根到叶子级别遍历树结构并在任何情况下绘制一个矩形,但如果节点恰好是一个叶子,也会填充矩形节点
该代码适用于较小的树,但对于具有42层节点的较大数据集,可重现性崩溃。尝试在第16层以下渲染节点时,上部DrawRectangle
调用会抛出OutOfMemoryException
,与32/64位或调试和发布配置无关。
画笔和画笔不会发生变化,因此它们存储在方法外的数组中。创建或处理对象没有问题。
这是我用来渲染树形图的递归方法:
/// <summary>
/// Renders a certain <see cref="Tree"/> onto the canvas.
/// </summary>
/// <param name="tree">The tree node to be rendered.</param>
/// <param name="g">The <see cref="Graphics"/> canvas to render the tree to.</param>
/// <param name="bounds">The rectangle available for the specified <paramref name="tree"/>.</param>
protected void RenderTree(Tree tree, Graphics g, RectangleF bounds)
{
if (tree.IsLeaf)
{
g.FillRectangle(brushes[tree.Depth], bounds);
g.DrawRectangle(pens[tree.Depth], bounds);
}
else
{
g.DrawRectangle(pens[tree.Depth], bounds);
if (bounds.Width >= bounds.Height)
{
float widthPerChild = bounds.Width / (float)tree.Children.Count;
for (int i = 0; i < tree.Children.Count; ++i)
{
RenderTree(tree.Children[i], g, new RectangleF(bounds.X + i * widthPerChild, bounds.Y, widthPerChild, bounds.Height));
}
}
else
{
float heightPerChild = bounds.Height / (float)tree.Children.Count;
for (int i = 0; i < tree.Children.Count; ++i)
{
RenderTree(tree.Children[i], g, new RectangleF(bounds.X, bounds.Y + i * heightPerChild, bounds.Width, heightPerChild));
}
}
}
}
对代码有什么问题有什么想法吗?或者它可能是GDI +的问题?
答案 0 :(得分:2)
感谢您的所有评论;我可以解决这个问题。我还测试了绘图过程的迭代版本,它没有改变任何东西,但给了我更好的调试选项。 问题似乎是我试图绘制的矩形太小(宽度和高度> 0,但大约10 ^( - 5)):在绘制矩形之前,我添加了一个阈值如果矩形的宽度或高度小于1/1000。当然,这使得OutOfMemoryException
不是很有帮助,因为您所评论的内存问题都没有显示任何可疑行为。