views:

647

answers:

2

Hi,

have I have a quesition regarding MVVM pattern in the uses case of diagramming.

What I have so far is a list of Items which are my Shapes.

ObservableCollection<ItemsViewModels> Items;

and a Collection of Connection of Items

ObservableCollection<ConnectionViewModel>

Each ItemViewModel has an ID and a ConnectionViewModel has two ID to connect the Items.

My ItemsViewModel Collection is bound to a itemscontrol which is layout on a Canvas.

With the ElementMouseDragBehavior I am able to drag my Items around. Now comes my big question =) How can I visualize my connections that I will be able to move the items around and the items stay connected with a line either straign or bezier.

I don't know how to abstract that with the mvvm pattern.

Thanks for any help...

A: 

There are many ways to accomplish this. With Silverlight though, there are few more challenges with layout and drawing the connecting lines. In WPF, I'd consider using an adorner layer and rendering the lines that way. However, Silverlight doesn't directly have an adorner layer, but it could be emulated (although in my suggestion below, I'm suggesting an alternative approach to adorners).

Here's one way I'd consider solving the problem and solving the problem.

  1. It doesn't appear that the MouseDragElementBehavior has any events that would indicate when an element is moving or has moved to a new location.
    • There also appear to be some major dragging bugs when the dragged object is set to contained within a canvas, so I'm not sure I'd use it.
  2. I'd create my own draggable surface (derive from Panel). You'd need to implement your own mouse handling, and a custom panel with a MeasureOverride and ArrangeLayout override. See this for more information about layout in Silverlight.
    • Simulating a canvas like dragging experience is relatively easy as there aren't too many challenges with measuring or arrangement really. You'd need to create either attached properties with the location of the shape, or actually add the location to the shape object. I'd probably go with the latter if it makes sense to have those values directly stored in your shape objects.
    • to make things draggable, you'll need to attach to a shape's mousedown/up and capture the mouse and do some simple dragging logic.
    • Optionally Add an event when things are being dragged and have completed being dragged.
    • when controls are removed from the panel, make sure you unwire any events you've attached so they are released during GC
  3. Create a second custom panel (or user control). This panel would be placed underneath the first dragging panel. The purpose of this panel would be to be bound to your connection objects (it will also need access to the original object positions of course, either directly or indirectly).
    • If you make it a panel, you could add lines per the connections and locations of the objects. You'll need to wire up to either the event I mentioned above, or directly to the a X,Y property changing event on the shape so that you can update the line objects as the shapes move.
    • or You could use a usercontrol and/or writeablebitmap to draw the lines. I'd suggest taking a look at the simple WriteableBitmapEx extension classes on Codeplex as it includes a simple line drawing algorithm. You would need to invalidate the bitmap and redraw the connections each time the shapes are updated.
WPCoder
A: 

Could this be of use for you?: The SpiderWebControl for Silverlight

Source is provided and it lists the following features

  • Adding, removing, renaming of nodes
  • Dragging of nodes
  • CTRL + Drag to drag a subtree/branch
  • CTRL + Drag on the canvas to pan around
  • Selections and hovers using VSM
  • Simple automatic layout with animations

Might not be exactly what you were after but it may give you a starting point.

John

john_man