Select All with Virtualization

Hi Walter,

In our application we have implemented virtualization in a similar way as in the demo app. We have a quite certain issue that when I do Ctrl + A. Only those nodes are selected which are in the view. The nodes outside the view are not selected. We want to select all the nodes including the ones which are not visible.

Can you suggest something for this ?

Yes, it is hard to set Part.IsSelected on something that doesn’t exist.

Perhaps you could put that state in the model data, so that when the Node or Link is created on demand you can automatically make it selected or not.

I am trying to load the Node and the Link based on their data which is set in SelectAll method. But for Virtualization I had used UpdateViewport method from demo application which calls the AddNodeForData method from the PartManager. This method now prevents it to bind the data to the template and the value probably is not rendered.

Causing a Node to be added to the Diagram by adding some data to the model will automatically bind that node to the data. So I do not understand how you are getting the behavior where the Node’s FrameworkElements are not being bound to some data.

I am trying to do the same approach that you suggested. I have added a property in Data and using DiagramSelectionChangedHandler event I am trying to set data.IsSelected properties to true.

This is just for the reason that the selection need not always happen from SelectAll method.

Now there is a method which adds/removes the nodes and links based on the viewport changes

 public void UpdateViewport(Rect oldview, Rect newview)
      {
        this.ViewportBounds = newview;

        Diagram diagram = Diagram;
        IDiagramModel model = diagram.Model;
        if (Equals(this.Diagram.CurrentTool, Diagram.DraggingTool))
        {
            return;
        }

        if (!OffscreenQueued)
        {
            OffscreenQueued = true;
            if (diagram.Dispatcher != null)
            {
                diagram.Dispatcher.BeginInvoke((Action)RemoveOffscreen);
            }
        }

        foreach (object data in model.NodesSource)
        {
            AddNodeForData(data, model);
            if ((data).IsSelected)
            {
                Node node = FindNodeForData(data, model);
                if (node != null)
                {
                    node.IsSelected = true;
                }
            }
        }

        if (model is ILinksModel lmodel)
        {
            foreach (object data in lmodel.LinksSource)
            {
                AddLinks(data, lmodel);
                if ((data).IsSelected)
                {
                    Link link = FindLinkForData(data, lmodel);
                    if (link != null)
                    {
                        link.IsSelected = true;
                    }
                }
            }
        }
    }

The following is my DiagramSelectionChangedHandler event handler

private void DiagramSelectionChangedHandler(object sender, SelectionChangedEventArgs e)
{
    
    ((Object[]) e.AddedItems).ToList().ForEach(part =>
    {
        if (part is Node node)
        {
            ((ShapeData)node.Data).IsSelected = true;
        }

        if (part is Link link)
        {
            ((ConnectorData)link.Data).IsSelected = true;
        }
    });
 ((Object[])e.RemovedItems).ToList().ForEach(part =>
{
    if (part is Node node)
{
    (node.Data).IsSelected = false;
  }

if (part is Link link)
{
    link.Data.IsSelected = false;
}
});
}

The problem is that during Virtualization if any link or node out of viewport the diagram calls the selectionChanged handler and makes the Data.IsSelected as false and as a result when I zoom out some of the elements come as unselected even though I had selected all of them when I had zoomed in.
I am not sure from where do I call Data.IsSelected = false

I haven’t tried this, but I believe you want to override GoXam for WPF v3

I do not think you need to override PartManager.OnNodeRemoved. I think your overriide of the SelectAll command should be setting the data property of all of the data.

this was overridden following the Virtualization example from the demo apps.
Also There can also be scenario that I select the few nodes rather than all nodes when I have zoomed in. If I am setting the Data.IsSelected only in SelectAll. the above case may fail.

I was assuming that you would be keeping the DiagramSelectionChangedHandler. But that is insufficient to handle the implicit selection required by the SelectAll command.