我正在尝试使用WPF绘制图像/图标网格.网格尺寸会有所不同,但通常为10x10到200x200.用户应该能够单击单元格,并且某些单元格需要每秒更新(更改图像)10-20次.网格应该能够在所有四个方向上增长和缩小,并且它应该能够切换到它所代表的3D结构的不同"切片".我的目标是找到一种适当有效的方法,根据这些要求绘制网格.
我目前的实现使用WPF Grid.我在运行时生成行和列定义,并使用Line(对于网格线)和Border(对于单元格,因为它们当前只是打开/关闭)在适当的行/列填充网格.(这些Line对象一直跨越.)

同时扩大了网格(按住NUM6)我发现,它吸引太慢重绘上每一个操作,所以我修改了它只需添加一个新的ColumnDefinition,Line并设置Border为每增长一个列对象.这解决了我的增长问题,也可以使用类似的策略来快速缩小.为了在模拟中更新单个单元格,我可以简单地存储对单元格对象的引用并更改显示的图像.通过仅更新单元内容而不是重建整个网格,甚至可以改变到新的Z级.
但是,在我完成所有这些优化之前,我遇到了另一个问题.每当我将鼠标悬停在网格上时(即使在慢速/正常速度下),应用程序的CPU使用率也会激增.我从网格的子元素中删除了所有事件处理程序,但这没有任何效果.最后,保持CPU使用率在检查的唯一办法是设置IsHitTestVisible = false为Grid.(为每个子元素设置这个Grid没有做任何事!)
我相信使用单独的控件来构建我的网格对于这个应用来说过于密集和不合适,并且使用WPF的2D绘图机制可能更有效.不过,我是WPF的初学者,所以我正在寻求如何最好地实现这一目标的建议.从我读过的内容来看,我可能会使用a DrawingGroup将每个单元格的图像组合成一个图像进行显示.然后,我可以为整个图像使用单击事件处理程序,并通过鼠标位置计算单击的单元格的坐标.但这似乎很混乱,我只是不知道是否有更好的方法.
思考?
更新1:
我接受了朋友的建议,并转而使用Canvasa Rectangle为每个单元格.当我第一次绘制网格时,我将引用存储Rectangle在二维数组中的所有内容,然后当我更新网格内容时,我只是访问这些引用.
private void UpdateGrid()
{
for (int x = simGrid.Bounds.Lower.X; x <= simGrid.Bounds.Upper.X; x++)
{
for (int y = simGrid.Bounds.Lower.Y; y <= simGrid.Bounds.Upper.Y; y++)
{
CellRectangles[x, y].Fill = simGrid[x, y, ZLevel] ? Brushes.Yellow : Brushes.White;
}
}
}
Run Code Online (Sandbox Code Playgroud)
最初绘制网格似乎更快,后续更新肯定更快,但仍然存在一些问题.
无论我鼠标移动的区域有多小,每当我将鼠标悬停在网格上时,CPU使用率仍然会超过几百个单元格.
更新仍然太慢,所以当我按住向上箭头键来更改Z级别(一个常见的用例)时,程序一次冻结几秒钟,然后看起来一次跳跃50个Z级别.
一旦网格保持~5000个单元格,更新大约需要一秒钟.这非常慢,5000个单元适合典型的使用案例.
我还没有尝试过这种 …
我一直在寻找工具来帮助检测阻止程序作为64位代码正常运行的错误.最近,我一直在玩弄Klocwork及其自定义检查器功能,这让我可以使用XPath将源代码导航为树.这对于正则表达式来说是一种"更聪明"的替代方法,但我无法让它知道类型.
例如,假设我想找到一个for使用a int或a long计数的循环的每个实例.以下代码很容易找到.
for (int i = 0; i < 10; i++)
// ...
Run Code Online (Sandbox Code Playgroud)
搜索此代码很简单,因为变量定义就在循环内部.但是,请考虑以下示例.
int i;
// ...
for (i = 0; i < 10; i++)
// ...
Run Code Online (Sandbox Code Playgroud)
这很难找到,因为变量定义与循环是分开的,并且必要的XPath表达式要么笨重,要么容易出错.
那么,自定义Klocwork规则可以找到这样的表达式,其中类型感知是必要的,包括解析typedef和#define语句?还有其他工具可以做到这一点吗?
编辑1:考虑以下示例.
typedef int myint;
void Foo() {
int i;
for (i = 0; i < 10; i++) {
Bar();
}
myint j;
for (j = 0; j < 10; j++) {
Bar();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在研究将大量(> 10M行)数量的C++代码移植到64位的方法.我查看了静态代码分析器和编译器标志,现在我正在研究可以进行常见重复更改的宏或其他工具.
我写了一些正则表达式,看看它们在实践中的表现如何,正如预测的那样,它们非常有效.也就是说,首先构建表达式需要一段时间,所以我想看看是否有任何可以自动执行更改的表达式或软件工具列表.
以下行是要匹配和修复的代码的原型示例.(为了澄清,这些行并不代表单个代码块,而是从不同的地方拉出的行.)
int i = 0;
long objcount;
int count = channels.count(ch);
for (int k = 0; k < n; k++) { /*...*/ }
Run Code Online (Sandbox Code Playgroud)
目标不是将代码彻底移植到64位,而是对代码执行第一次传递以减少需要手动检查的代码量.可以错过一些必要的更改,并且可能会做出一些错误的更改,但这些更改应该最小化.
Visual Studio是将用于转换工作的IDE,因此适用于VS的东西是一个优点.成本不是问题.
我在准备用于 64 位端口的一些(C++)代码中发现了一个与此类似的片段。
int n;
size_t pos, npos;
/* ... initialization ... */
while((pos = find(ch, start)) != npos)
{
/* ... advance start position ... */
n++; // this will overflow if the loop iterates too many times
}
Run Code Online (Sandbox Code Playgroud)
虽然我严重怀疑这实际上会在内存密集型应用程序中引起问题,但从理论的角度来看还是值得的,因为可能会出现类似的错误,从而导致问题。(在上面的例子中更改n为 a short,即使是小文件也可能溢出计数器。)
静态分析工具很有用,但它们不能直接检测这种错误。(无论如何还没有。)计数器n根本不参与while表达式,所以这不像其他循环那样简单(类型转换错误会导致错误消失)。任何工具都需要确定循环将执行超过 2 31次,但这意味着它需要能够估计表达式(pos = find(ch, start)) != npos将评估为真的次数——这可不是一件小事!即使一个工具可以确定循环可以执行超过 2 31次(比如说,因为它识别出find函数正在处理一个字符串),它怎么知道循环不会执行超过 2 64 次次,也溢出一个size_t值? …
我正在写一个着色器,它偶尔会在2D地图上产生一个亮点.("闪光"只是一个颜色较亮的像素.)我希望闪闪发光的块随机均匀地分布在(无限)平面上,但我希望闪闪发光是基于X和Y坐标的确定性.我尝试从坐标创建种子并Random从该种子创建Java ,但到目前为止,我的尝试导致了可识别的模式.此功能将被频繁调用(数百万次),因此性能至关重要.
我首先尝试模仿我的hashCode()实现,它使用素数乘数来避免冲突.这导致地图上出现明显的伤口,其中一系列点共享相同的种子.
然后,我尝试通过连接坐标来创建种子,如下所示:
long seed = ((long) x << 32) | (long) y;
Random rand = new Random(seed);
Run Code Online (Sandbox Code Playgroud)
这似乎也导致了图案化数据,尽管模式并不那么明显.选定的坐标以线条显示,根本不均匀分布.
我避免使用MD5或其他加密哈希算法,因为我害怕性能影响.
我想利用.NET的数据框架,但我对它们的工作原理有点困惑,我不确定我想要的是不可能的.(我已经用PHP框架做了很多这样的事情,所以我希望.NET可以做同样的事情!)简而言之,我希望我的业务逻辑与数据库无关,并且在某种意义上,我不知道这个事实是它根本就是一个数据库.
像这样的查询会让我感到恼火:
var productNames =
from p in context.Products
where seller.SellerID == mySeller.SellerID
select p.Name;
Run Code Online (Sandbox Code Playgroud)
相反,我想做:
var productNames =
from p in context.Products
where seller == mySeller
select p.Name;
Run Code Online (Sandbox Code Playgroud)
本质上,我希望我的业务逻辑不关心 ID映射.部分地,这是因为在几个表中,ID具有实际意义.(我正在使用的一些表是从另一个应用程序域导入的,我需要能够直接使用这些ID,但对于我自己的类型,这些ID是偶然的.)
这是示例中的一个小点,但总的来说,我希望能够完全在对象世界中工作,或多或少地忘记底层数据库的现实.这只是为我的类定义等价运算符的问题吗?
总结:什么.NET数据框架为我提供了对象世界最干净的数据库抽象?
c++ ×3
32bit-64bit ×2
64-bit ×2
c# ×2
2d ×1
abstraction ×1
coordinates ×1
database ×1
dom-events ×1
drawing ×1
grid ×1
hash ×1
java ×1
javascript ×1
klocwork ×1
linq ×1
mousemove ×1
portability ×1
seed ×1
wpf ×1