Center Node


I try to get a Node centered in the panel. But it doesn´t work. This is my method:

private void CenterNode(Node node)


DiagramPanel myPanel = myDiagram.Panel;

double x = node.Position.X + (node.ActualWidth / 2) - (myPanel.ViewportWidth / 2);

double y = node.Position.Y + (node.ActualHeight / 2) - (myPanel.ViewportHeight / 2);

myPanel.Position = new Point(x, y);


I guess that I need to consider the panel.Scale but I don´t know how. Or did I miss something else?

I could also use myPanel.makeVisible(node, Rect.Empty) but this centers a node just if it is not already somewhere on the screen.


<go:Diagram x:Name="myDiagram" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" . . . />

[code] public void CenterNode(Node node) {
if (node == null) return;
DiagramPanel panel = node.Panel;
if (panel == null) return;
// get the bounds of the Node, in model coordinates
Rect r = node.Bounds;
// get the bounds of the visible extent of the view, in model coordinates
Rect v = panel.ViewportBounds;
// scroll the panel so the center of the node is centered in the view
panel.Position = new Point(r.X + r.Width/2 - v.Width/2, r.Y + r.Height/2 - v.Height/2);

private void Button_Click(object sender, RoutedEventArgs e) {
  CenterNode(myDiagram.SelectedPart as Node);

Thanks! It works!

I didn´t know that there is a difference between panel.ViewportWidth and panel.ViewportBounds.Width.

IScrollInfo.ViewportWidth is in device-independent pixel units.

DiagramPanel.ViewportBounds is in model coordinates. Although, as you realized, when the DiagramPanel.Scale is 1.0, the two widths will be the same.

Since you’re not the first person to ask for this, in version 1.1 we’ll add a DiagramPanel.CenterPart method.


I apply your method to center on a node choosen on a treeview (representing data):

SphItem oItem = (SphItem)tvVars.SelectedItem;            
            QD_Node oData = QDEnv.QD_Model.FindNodeByKey(oItem.ID.ToString());
            if (oData == null) return;
            Node oNode = myDiagram.PartManager.FindNodeForData(oData, QDEnv.QD_Model);
            if (oNode == null) return;

Is it ok ? I didn’t found a function that give me the node from a key.
It seems as 2 lists run, that we could probably improve.


That code looks OK to me. Does it work well for you?

If you are concerned about look-up performance, both of those Find… methods use hash tables. They get called a lot.