Changing viewmodel data through diagram

8 posts, 2 answers
  1. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 19 Sep 2012 Link to this post

    Hi,

    Situation:
    • I have a list of "Regions" i.e. ObservableCollection<Region>
    • I have a list of "Treatments" i.e. ObservableCollection<ITreatment>
    • I need to add a Treatment or a series of treatments in chain to a region
    • A treatment can be applied to one or more "Regions"

    Concept:
    • List of Regions in a listbox
    • List of treatment in a listbox
    • Drag a region to RadDiagram
    • Drag a treatment to RadDiagram and connect it as Target of region.
    • Drag another region to RadDiagram and use this as source to the current treatment
    • The treatment is added into ObservableCollection<ITreatment> property of both the regions.

    Is this possible through RadDiagram? How do I go about it?

    Thanking you in advance.
  2. Answer
    Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 24 Sep 2012 Link to this post

    Hi Deepak,

    I attached a sample solution to get you started on your task. Basically, you need to create a custom GraphSource collection for the RadDiagram. You can examine this documentation for more information on how to populate the diagram with data items. However, please have in mind that as you'll change the GraphSource of the RadDiagram by dropping items on it, you'll have to create a custom collection deriving from the IObservableGraphSource interface (in the documentation sample, the example illustrates how to derive your collection from IGraphSource instead, but this can't work in a drag/drop scenario, where the RadDiagram.GraphSource collection should be changed to reflect the newly added items).

    Also, in order to implement the drag/drop scenario you can have a look at this tutorial. It demonstrates an approach where the RadDiagram is populated declaratively with IDiagramShape items but the approach in a databinding scenario is similar - you only need to populate the RadDiagram.GraphSource collection.

    Kind regards,
    Tina Stancheva
    the Telerik team

    Time to cast your vote for Telerik! Tell DevPro Connections and Windows IT Pro why Telerik is your choice. Telerik is nominated in a total of 25 categories.

  3. DevCraft banner
  4. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 24 Sep 2012 Link to this post

    Hi Tina,

    Thanks heaps for the example. It has helped in planning for my needs. The only thing is that I will have to create an interface INode rather than derive from NodeBase as my Region derives from a base class in SimpleMVVMToolkit and I cannot modify it. Hope this works to implement the DropPostion as you have shown. Thanks for this as I was wondering how I would go about specifying the drop position.

    I will work on this further and will post an update once I achive my goal. The example is very promising and I should get a result out of it.

    Thank you once again!
  5. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 08 Oct 2012 Link to this post

    Hi Tina,

    Thanks for that example, I can now add items from a listbox to RadDiagram. I have data store class that implements ObservableGraphSourceBase. I have a property of this type in my main viewmodel which is bind to the GraphSource of the RadDiagram.

    The drag and drop works well with the node now. I have override AddNode method that prevents an item in the list to be added twice. (i.e. for Region Type)
    Since I have another listbox with items of different type (Treatment Type), I want to make sure that the connection is not made between the Region Type. I only want to allow connection between Region and Treatment.

    I tried to override the AddLink method, but it is invoked too early and my target is null. (Always)

    I have also tried to catch it through ConnectionManipulationCompleted. But I cannot see the types of Source and Target through the ManipulationRoutedEventArgs. 

    Is there a way, I can check the data types (NOT shape type) of source and target and keep/remove connection if the types are different?

    Many thanks again.

    Update 1:

    I could get the data type for Source using e.Connection.Source.Content. The target is still null for ConnectionManipulationCompleted. Why?


    Update 2: 

    Now if I select the connection; select the end connector; and then connect it to target, the Target property / target.Content for the connection in ConnectionManipulationCompleted is populated. Hence I can removed the connection using Diagram.SelectedItem. Why isn't the target property populated the first time when the connection is made?
  6. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 08 Oct 2012 Link to this post

    Hi all,

    Finally, I have worked out a solution for this one. For anyone interested - 

    private void TDiagram_ConnectionManipulationCompleted(object sender, ManipulationRoutedEventArgs e)
           {          
               e.Connection.ConnectionType = ConnectionType.Bezier;
               e.Connection.BezierTension = 1;
     
               if (e.ManipulationStatus == ManipulationStatus.Attaching)
               {
                   var target = e.Connector.Shape.Content;
     
                   if (e.Connection.Source != null && target != null)
                   {
                       if (e.Connection.Source.Content is SubregionModel && target is SubregionModel)
                       {
                           var diagramSource = TDiagram.GraphSource as DiagramSource;
                           if (diagramSource != null)
                           {
                               diagramSource.InternalLinks.RemoveLast();
                           }
                       }
                   }
               }
           }

    • I got access to target through e.connector.Shape (Thanks to one of the threads in this forum)
    • if the source and the target is of same data type (i.e. SubregioModel in my case), I simply remove the last link from InternalLinks

    Thanks for looking. 
    Cheers!
  7. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 09 Oct 2012 Link to this post

    Hi Tina,

    I have encountered another issue with the RadDiagram. This is also present in the sample you attached.

    The problem is that if I add a item (Region 1) from a ListBox to the Diagram for the first time, it works fine. I then add another item (Region 2) from the ListBox, it works fine too. But when I try to add Subregion 1 again, it doesn't display in the diagram but adds it to the InternalItems collection. 

    I need to be able to add two shapes of the same data type.

    I have just commented out the checking it does in AddNode method and it still does not add to the diagram.

    Edited sample can be downloaded from my skydrive

    Cheers!
  8. Answer
    Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 10 Oct 2012 Link to this post

    Hello Deepak,

    I am glad that you found a solution to the links issues you had.

    Now, in order to implement the last described requirement, you'll need to make sure that the drop operation each time adds a new instance of the respective class. With the current solution when you add twice the Region1 object, the same instance of the class is added twice in the GraphSource of the RadDiagram. But the GraphSource can't recognize the second instance as a new object as the instance is already part of the InternalItems collection and this is why the RadDiagram doesn't display a new shape.

    However, if you make sure that the AddNode method adds a new instance of the items each time, you'll be able to drop one item multiple times. I modified your solution to demonstrate this approach.

    Kind regards,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  9. Deepak Shakya
    Deepak Shakya avatar
    118 posts
    Member since:
    Aug 2007

    Posted 10 Oct 2012 Link to this post

    Hi Tina,

    Thanks for the example. Creating new instance of the class in AddNode solved the problem.

    Thanks heaps!
Back to Top
DevCraft banner