We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Update Datasource when diagram changes

I'm loading a diagram from a datasource, and using the LayoutManager to make things look nice - that all works fairly easily. Now I want to modify the diagram, and eventually store the modified datasource. I have fairly tight rules on how the diagram can be changed: about the only actions that the user can perform directly on the diagram are creating and deleting connectors so I'm trying to work out how to inform my ViewModel that this has happened. I thought that the simplest thing would be to monitor the Connectors collection so I've added and ObservableCollection<ConnectorViewmodel> and bound it to the sfDiagram.Connectors property. As the LayoutManager generates the layout my code receives lots of ItemAdded events in the collection (good), and when the user deletes a connection it gets ItemRemoved events (also good). However, I'm also getting these ItemRemoved events when the sfDiagram control is not being displayed (it's on a TabControl), and my ViewModel has no way of differentiating these. Obviously I can't have the diagram being modified when the user just navigates around the application, so it appears that monitoring the sfDiagram.Connectors property isn't going to work for me.

How do you recommend I keep my DataSource in sync with the changing connectors in my diagram?


11 Replies

DT Deepa Thiruppathy Syncfusion Team January 17, 2023 07:04 AM UTC

Hi Russell,


Requirement: ItemDeleted event is getting fired when no items displayed in the diagram page


We are not getting your exact scenario. We request you to clarify below details from your side,


  1. What kind of layout you are using?
  2. Do you edit the data source at code behind when there are no items displayed in the diagram page?
  3. Do you using instance of NodeViewModel as data-source item or using any custom class objects for data source?
  4. If possible, we request you to share any video representation for your complete scenario?


Regards,

Deepa Thiruppathy



RU Russell replied to Deepa Thiruppathy January 17, 2023 08:27 AM UTC

Hi Deepa,


This is a quick response - I'll try to provide something larger later.

I have a tabbed display, and on one of the tabs I have an sfDiagram. I load my data source into the diagram, and the layout manager converts the data source into a nice layout. I then switch to another tab, and the ItemRemoved event is raised for the Connections collection which is bound to the diagram's Connectors dependency property. 

In my code behind I am accessing the ConnectorTargetChangedEvent and ConnectorSourceChangedEvent to prevent the user from removing connectors. Neither of these fire when switching tabs.

Rather than trying to diagnose this specific issue, I'd just be happy to know what the recommended way of updating a datasource is when changes are made to a diagram.



RU Russell replied to Deepa Thiruppathy January 17, 2023 11:59 PM UTC

Hi Deepa,

I've attached a project which demonstrates my problem. There are two tabs, one containing a diagram which is created from a DataSource. When I delete a connection, the ConnectionsChanged event fires but the ParentsChanged event does not (I've therefore added code to the ConnectionsChanged event to update the Parents). Once the connection has been deleted, if you switch tabs and then return to the diagram, the application raises a Null access exception and crashes. The exception seems to occurs in the LayoutManager.


Attachment: GridDatasource_dfadd6be.zip


DT Deepa Thiruppathy Syncfusion Team January 18, 2023 01:38 PM UTC

Hi Russell,


Reported issue: Application crash when switch between diagram and tab control after delete connector from diagram.


We can reproduce the issue and we have validated it in your application. You have reset the source node and target node once connector is deleted from diagram which deleted the connector at view and maintaining the source and target node values at view model level. This causes application crash when switch between diagram and tab control once connector deleted from diagram page.


Code snippet:

private void TrafficPatternPanel_ConnectorTargetChangedEvent(object sender, ChangeEventArgs<object, ConnectorChangedEventArgs> args)

{

    if (args.NewValue.Node == null && args.OldValue.Node != null)

    {

        NodeViewModel node = args.OldValue.Node as NodeViewModel;

 

        //Reset target node when it is changed to null from target node.

        (args.Item as ConnectorViewModel).TargetNode = node;

    }

}

 

private void TrafficPatternPanel_ConnectorSourceChangedEvent(object sender, ChangeEventArgs<object, ConnectorChangedEventArgs> args)

{

    if (args.NewValue.Node == null && args.OldValue.Node != null)

    {

        NodeViewModel node = args.OldValue.Node as NodeViewModel;

 

        //Reset source node when it is changed to null from source node.

        (args.Item as ConnectorViewModel).SourceNode = node;

    }

}


If you remove the above highlighted codes from your application, it will not be getting any crash. We request you share the reason for resetting source node and target node after deleted the connector at diagram page. Based on your need, we will validate the scenario and assist you further.



RU Russell January 18, 2023 10:46 PM UTC

Hi Deepa,


I copied that code from your article 174804, to prevent the disconnection of a connector. I confirm that commenting out those lines does prevent the exception from occurring. However, it is now possible to disconnect one of the connections and leave it unconnected in the diagram. In this case, the exception happens again when switching tabs. I believe this is when the LayoutManager tries to refresh the layout.

I don't want to allow dangling connections in my diagram. Users are only allowed to delete existing connections, and to add new connections between certain types of node. How can I achieve this without having the application crash?



DT Deepa Thiruppathy Syncfusion Team January 20, 2023 12:46 PM UTC

Hi Russell,


Reported issue: How to restrict dangling connector in the diagram


To preserve your requirement with this scenario when delete a connector, we have enabled a flag when connector is getting deleted at ItemDeleting event. Based on the flag value, we have skipped the source and target node resetting process at TrafficPatternPanel_ConnectorSourceChangedEvent and TrafficPatternPanel_ConnectorTargetChangedEvent events.


Modified sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/GridDatasource_modified1984339366


Note: If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.



RU Russell January 20, 2023 10:19 PM UTC

I confirm that deleting a connection no longer causes an exception to be raised when switching between tabs. However, deleting a node does cause an exception to be raised, so this solution is not especially useful just yet.


To reiterate, what I'm really after isn't a solution to this specific exception. I'd like to know SyncFusion's recommended method for keeping the DataSource synchronised with any changes to the DiagramViewModel. It's quite possible that what I'm doing is completely unnecessary, and that you have a much simpler way of doing it. I'd much rather jump straight to that recommendation rather than chase down a whole series of exceptions.



RU Russell January 20, 2023 11:24 PM UTC

I'll add a little more detail about my requirements. I'm quite happy to make most changes to the diagram by changing the DataSource - for example, by using a context menu to add new nodes. However, there are a few things that can't easily be done that way, such as creating new connections, as well as deleting nodes and connections. I don't really want the user to move nodes and connections around, which is why I'm very happy to leave all that to the layout manager.

I've added the context menu to the example - I'm now getting an exception when I remove a node from the DataSource (as well as when I delete a node in the diagram).


Attachment: GridDatasource_89d7224b.zip


PP Prakash Perumal Syncfusion Team January 23, 2023 10:46 AM UTC

Hi Russell,


Requirement: Option to keep the DataSource synchronized with any changes to the DiagramViewModel.


Currently we don't have direct support to synchronize datasource with the changes made in the diagram interactively. So, we suggest you to continue with the current approach. We have modified the project to avoid exceptions raised on deleting the nodes or connector.


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/GridDatasource_-_modified-504059523


Regards,

Prakash



RU Russell January 26, 2023 02:46 AM UTC

OK, so it seems to me that you're saying that sfDiagram is only suitable as an output tool, and that there isn't really any way to parse the diagram drawn by the user. This means that it's really just a pretty toy, but has no actual utility in terms of configuring a system. That being the case, I think I'll abandon trying to use it and revert to my previous tool - it's not perfect but it's good enough.



DT Deepa Thiruppathy Syncfusion Team January 31, 2023 02:43 PM UTC

Hi Russell,


As we mentioned in our last update, we do not currently have direct support for synchronizing the data source with changes made to the diagram interactively. This behavior can be achieved at the application level as a workaround. Any changes made to the diagram page will be updated to the data source through events, so it is possible to keep the data source synchronized with the changes in the SfDiagram control.


We have logged this as a feature request, and it will be available in one of our upcoming releases.


You can follow the link below to check the status of the feature:

Support to update the datasource data when updating diagram elements collection and vice versa in WPF | Feedback Portal (syncfusion.com)


Regards,

Deepa Thiruppathy


Loader.
Live Chat Icon For mobile
Up arrow icon