Is there any event where I can handle Shape or Connection deletion events?
I can not see such events right now.
Problem : In my diagram, I stored values with shapes & connections. Now when user delete anything it checks the values & process for deletion. But with RadDiagram how can I cancel deletion if my shape or connection value not satisfy for delete?
10 Answers, 1 is accepted
We don't provide such an event because most operations in the RadDiagram are implemented through a command. And you can modify all commands to customize the operations to better fit your scenario.
For example in this demo solution, you can see an example of how to modify the DiagramCommands Save and Open. Basically you need to register a command binding for the commands in the static constructor of the page.
In your case you can register a command binding for the DiagramCommands.Delete command as demonstrated in the attached sample and implement custom logic in the ExecuteDelete method. If you don't do anything there, the RadDiagram elements won't be removed.
Regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
Please correct me if I am wrong but hooking up to Commands is only possible through Buttons. What if I want to do something when a link is deleted/deleting using keyboard and not button click event? For example, I have a property is my source class called "targetShapeName" that is set when the connection status is "Attaching". I need to be able to set this property to null when the link is deleted.
Any workarounds?
The DiagramCommands.Delete execution method will be fired even when the delete operation is triggered through the keyboard Delete buttons. This is due to the fact that the RadDiagram has predefined KeyBindings, binding keyboard keys to DiagramCommands (read more). This is why you can handle the DiagramCommands.Delete execution method to change the targetShapeName property value in your case as well.
Also, if you're building the RadDiagram from a business collection of items, you can handle the deletion of a link in the view model. The approach in this case would depend on the type of the collection bound to the RadDiagram.GrapghSource, but basically you can track when the collection of links is changed or when a link is removed from the GraphSource.
Kind regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Thanks for your help. The ExecuteDelete command was not hit by deleting using Keyboard as I had set the GraphSource. As you said I could capture this event in my viewmodel by subscribing to the event:
DiagramSource.InternalItems.CollectionChanged +=
new
InternalItems_CollectionChanged;
DiagramSource.InternalLinks.CollectionChanged +=
new
InternalLinks_CollectionChanged;
Is this what you mean or is there a better way to do it. I would need to unsubscribe to this event when the view is no longer in use, wouldn't I?
Cheers!
As you're binding the RadDiagram GraphSource to a business collection and you want to add/remove items out of it, we recommend deriving the business collection from either the ObservableGraphSourceBase<TNode,TLink> or the SerializableGraphSourceBase<TNode, TLink>
class. Both of these classes will allow you to override the RemoveLink method which is triggered when a link is removed from the RadDiagram collection of items. You can use this method to cancel the delete by returning a false value in it.
The SerializableGraphSourceBase<TNode, TLink> class is the better choice when you need to copy/paste the Shapes/Connections of the diagram along with their databound content. As by default the RadDiagram serialization mechanism serializes the list of properties described here, it doesn't serialize the DataContext of the items and this is why when you bind the content of the shapes/connections, a copy/paste operation won't keep the binded content. This is why we've provided the SerializableGraphSourceBase<TNode, TLink> class - if your GraphSource collection derives from it, you can override the SerializeNode/Link and DeserializeNode/Link methods to manually serialize the business properties that you need.
I attached a sample solution demonstrating how to derive the GraphSource collection from the SerializableGraphSourceBase<TNode, TLink> class. Please note you need to layout the RadDiagram to see the full structure of the databound diagram through the Layout button. And I've overriden the RemoveLink() method to cancel the delete of a link. Let me know if that helps.
Regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Thanks for your reply. I am a bit confused with the whole thing about serialisation using MVVM.
- I had my source derived from ObservableGraphSourceBase<IMyNode,MyLink>
- Override AddNode to get nodes in the diagram
- Calling it from codebehind on "OnDiagramDrop" utilising e.Data
Now if I derive it from SerializableGraphSourceBase<IMyNode,MyLink>, without making any changes, I can add nodes to the diagram as it is still calling my old method - "AddNode" in my source. But now when I try to copy the node and paste it,
- it throws an error - Cannot create a new instance of an Interface
This may be because now it is trying to call - CreateNode instead of AddNode that is called when Drop occurs.
CreateNode takes IShape as parameter. How do I pass my IMyNode as IShape? I am a bit confused as there aren't many examples dealing with serialisation using MVVM in the help section.
The content of my node is a class and how do I serialise it as it is not a string?
I hope this is "clear".
Any help and sample would be highly appreciated. Maybe a bit more detailed example in the online help regarding serialisation would be helpful, esp using MVVM.
Would somebody have an example of serialising/deserialising Node/Link using SerializableGraphSourceBase?
Any help would be appreciated.
Cheers!
The solution I previously attached demonstrates how to serialize a business property from the class that described the RadDiagramShapes - in the GraphSource implementation you can take a closer look at the override of the SerializeNode and DeserializeNode methods. The implemented code serializes the Label property so that when you copy a RadDiagramShape and paste it, its content (databound to the Label property) will be pasted as well.
If the solution doesn't work for you, can you please modify it to better demonstrate your approach or send us a project demonstrating your scenario, so that we can take a closer look at it and advice you on how to get over the described exceptions? Thank you in advance.
Also, we've included an article on how to serialize a databound RadDiagram - the article will be available with the next upload of our documentation by the beginning of next week. And you will be able to find it under the HowTo section of the RadDiagram documentation.
Kind regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Thanks again. I will play with the serialisation a bit more and will let you know if I run into any problems. The example that you sent me did provide me with a concept of serialisation and I am working on it. I still feel that I truly do not how we persist the data. The documentation is something I will look forward to and will let you know if this provides an insight into what I need to know.
I have been playing around a bit trying to save the diagram along with all the input data in the form of project file. I am using codeplex project called "sharpserializer". This basically saves all my data. Since I am using this to serialize the project data I wanted to serialize the GraphSource along with it. So when the project is loaded, the diagram will be loaded as well as it the GraphSource is Bind to my source derived from SerializableGraphSourceBase.
The problem I faced was that I could not serialise the internal items and links as it does not have a public setter, which is a requirement for the tool I am using. Hence I have to create properties ObservableCollection<INode> and ObservableCollection<ILink> with getter and setter to store the values of InternalItems and InternalLinks during Serialisation and then re-populate them from new properties during deserialisation.
I could do this and not worry about overriding the (De)SerializeNode/Link.
But I would like to use the Telerik serialisation so that everything remains consistent. Will venture into this when I read the documentation and see how I go.
Thanks heaps once again. You have been so patient and such great help.
Cheers!
We want to keep you updated on the status of our new Diagram-Serialization-In-DataBound-Scenarios - it is uploaded already and you can read it here. Keep in mind that the Serialization mechanism saves and loads the objects / properties you use via strings. In other words if you save a property of custom type, the SerializationInfo will save its ToString() method's returned value. So you have to provide methods that extract the information you need from the string you have saved in the SerializationInfo.
Please let us know if further questions arise.
Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.