1

我正在尝试在 C#/wpf 中编写一个类似于应用程序的绘图来生成管道和节点网络。需要的功能之一是在用户单击节点或将鼠标悬停在节点上时更改节点的颜色(2 种单独的突出显示颜色)。

目前,我的图形代码结构如下:

我有一个全局节点列表Node.list和一个循环遍历列表并读取每个节点的坐标并在该值处放置一个椭圆的绘制事件。(有一个嵌入式 Winform 面板用作绘图表面,因此不渲染绘制事件)单击不存在点的绘图表面已经添加了一个新节点Node.list,然后触发绘制事件。在它存在的地方单击它会弹出一个菜单,可以在其中调整坐标和其他属性。它还将isHighlightedbool 属性设置为 true,其中绘制事件的逻辑捕获并以不同颜色绘制点。这是绘画事件代码:

Node nodes = new Node();                                  
        for (int q = 0; q < Node.list.Count; q += 1)
        {
            nodes = Node.list[q];
            if(Node.list[q].redHL) //Clicked
            {
                g.FillEllipse(black, Convert.ToInt32(nodes.xCord) - 8, Convert.ToInt32(nodes.yCord) - 8, 19, 19);
                g.FillEllipse(red, Convert.ToInt32(nodes.xCord) - 6, Convert.ToInt32(nodes.yCord) - 6, 15, 15);
            }

            else //Regular Nodes
            {                    
                g.FillEllipse(black, Convert.ToInt32(nodes.xCord) - 8, Convert.ToInt32(nodes.yCord) - 8, 19, 19);
                g.FillEllipse(yellow, Convert.ToInt32(nodes.xCord) - 6, Convert.ToInt32(nodes.yCord) - 6, 15, 15);
            }
            if (Node.list[q].yellowHL) //Hovered
            {                    
                g.FillEllipse(black, Convert.ToInt32(nodes.xCord) - 8, Convert.ToInt32(nodes.yCord) - 8, 19, 19);
                g.FillEllipse(blue, Convert.ToInt32(nodes.xCord) - 6, Convert.ToInt32(nodes.yCord) - 6, 15, 15);

            }
        }

这种方法非常有效,直到我尝试设置代码以便将鼠标悬停在某个点上时它会改变颜色。我尝试的第一件事是在鼠标移动事件中放置一个 if 语句,如下所示:

row = pointExists(e.X, e.Y);

if(row != -1)
   /* Highlight point */
   Node.list.Count[row].isHighlighted = true;
else
   /* unhighlight all points */
   for(u = 0; u > Node.list.Count; u += 1)
      Node.list[u].IsHighlighted = false;

这行得通……但它会导致屏幕疯狂地闪烁,因为每次移动鼠标时都会触发绘制事件!

我试图设置一些逻辑,以便只有当鼠标第一次离开该区域时才会触发绘制事件,并且成功了......有点。我从上面提到了这个 franken-logic-statement:

            if (row != -1  )
            {
                if (Node.inRegion)
                {
                    Node.lastNode = row;                        
                    for (int u = 0; u < Node.list.Count; u += 1)
                        Node.list[u].yellowHL = false;
                    Node.list[row].yellowHL = true;
                    Node.inRegion = false;
                    Node.outRegion = true;                        
                    wfSurface.Invalidate();
                }
            }
            else
            {
                if (Node.outRegion)
                {                        
                    if (Node.lastNode != 0)
                        Node.list[Node.lastNode].yellowHL = false;
                    Node.inRegion = true;
                    Node.outRegion = false;
                    wfSurface.Invalidate();
                }                    
            }

不完全简洁。

在我不得不开始投入更多逻辑之前,上述方法一直有效。当用户想要绘制一个节点时,我必须加入其他条件,例如“用户是否选择了链接的起点”,这些条件会改变什么颜色/何时突出显示节点。

有人对如何最好地解决这个问题有任何想法吗?我试过检查这个家伙的方法:

http://www.codeproject.com/Articles/8494/DrawTools

但在浏览了他的源代码 20 分钟后不久就放弃了(应用程序对我的理解来说太复杂了)。我想我可能完全错了......在上面的文章中,那个人提到使用命中测试来检查用户是否点击了绘制的图形。我只是查询了坐标列表,看看是否已经在那里绘制了一个节点,这有点像一个 hacky 解决方案......必须有一种更智能的方法来解决这个问题。

多谢你们,

猎人

4

0 回答 0