This is a migrated thread and some comments may be shown as answers.

add shapes in MVVM

4 Answers 367 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Affreux
Top achievements
Rank 1
Affreux asked on 01 Jun 2016, 03:44 PM

Hello,

I'm using a RadDiagram in my application. The GraphSource is backed by a ViewModel.

I need to draw shapes on the diagram, and have them added to the GraphSource. How can I achieve that?

 

I created a small test project, below. It has a window and a View Model.

At present, when I draw a path, new MyBaseNode object is created, but none of its properties have a value.

 

01.<Window x:Class="MainWindow"
04.        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
05.        xmlns:primitives="clr-namespace:Telerik.Windows.Controls.Diagrams.Primitives;assembly=Telerik.Windows.Controls.Diagrams"
08.        xmlns:my="clr-namespace:MvvmShapes"
09.        mc:Ignorable="d"
10.        Title="MainWindow"
11.        d:DesignWidth="800"
12.        d:DesignHeight="300"
13.        Height="350"
14.        Width="525">
15.    <Window.DataContext>
16.        <my:MyViewModel />
17.    </Window.DataContext>
18.    <Grid>
19.        <telerik:RadDiagram GraphSource="{Binding Graph, Mode=OneTime}"
20.                            ActiveTool="{Binding DiagramTool}">
21.            <telerik:RadDiagram.ShapeStyle>
22.                <Style TargetType="telerik:RadDiagramShape">
23.                    <!-- ce style relie les propriétés du ViewModel aux propriétés des formes dans le diagramme -->
24.                    <!-- position -->
25.                    <Setter Property="Position"
26.                            Value="{Binding Position, Mode=TwoWay}" />
27.                    <!-- rotation -->
28.                    <Setter Property="RotationAngle"
29.                            Value="{Binding RotationAngle, Mode=TwoWay}" />
30.                    <!-- width and height -->
31.                    <Setter Property="Width"
32.                            Value="{Binding Width, Mode=TwoWay}" />
33.                    <Setter Property="Height"
34.                            Value="{Binding Height, Mode=TwoWay}" />
35.                    <Setter Property="Content"
36.                            Value="{Binding Content, Mode=OneTime}" />
37.                    <Setter Property="Template">
38.                        <Setter.Value>
39.                            <ControlTemplate>
40.                                <TextBlock Text="{Binding Content}" />
41.                            </ControlTemplate>
42.                        </Setter.Value>
43.                    </Setter>
44.                </Style>
45.            </telerik:RadDiagram.ShapeStyle>
46.        </telerik:RadDiagram>
47. 
48.        <StackPanel HorizontalAlignment="Left">
49.            <Button Command="{Binding CommandPointer, Mode=OneTime}"
50.                    Content="Pointer" />
51.            <Button Command="{Binding CommandLine, Mode=OneTime}"
52.                    Content="Line" />
53.        </StackPanel>
54.    </Grid>
55.</Window>

 

001.Imports Telerik.Windows.Diagrams
002.Imports Telerik.Windows.Controls.Diagrams.Extensions.ViewModels
003. 
004. 
005.Public Class MyViewModel
006.    Inherits Telerik.Windows.Controls.ViewModelBase
007. 
008.    Public Property Graph As New MyGraphSource()
009. 
010.    Private _diagram_tool As Telerik.Windows.Diagrams.Core.MouseTool
011.    Public Property DiagramTool As Telerik.Windows.Diagrams.Core.MouseTool
012.        Get
013.            Return _diagram_tool
014.        End Get
015.        Set(value As Telerik.Windows.Diagrams.Core.MouseTool)
016.            _diagram_tool = value
017.            OnPropertyChanged("DiagramTool")
018.        End Set
019.    End Property
020. 
021.    Public ReadOnly Property CommandPointer As ICommand
022.        Get
023.            Return New CommandImpl(Sub() DiagramTool = Core.MouseTool.PointerTool)
024.        End Get
025.    End Property
026. 
027.    Public ReadOnly Property CommandLine As ICommand
028.        Get
029.            Return New CommandImpl(Sub() DiagramTool = Core.MouseTool.PathTool)
030.        End Get
031.    End Property
032.End Class
033. 
034.Public Class MyGraphSource
035.    Inherits ObservableGraphSourceBase(Of MyBaseNode, MyLink)
036. 
037.    Public Sub New()
038.        Dim node1 As New MyBaseNode() With {.Content = "node 1", .Position = New Point(100, 100), .Width = 60, .Height = 30}
039.        Dim node2 As New MyBaseNode() With {.Content = "node 2", .Position = New Point(400, 100), .Width = 60, .Height = 30}
040.        Dim node3 As New MyBaseNode() With {.Content = "node 3", .Position = New Point(100, 200), .Width = 60, .Height = 30}
041.        Dim node4 As New MyBaseNode() With {.Content = "node 4", .Position = New Point(400, 400), .Width = 60, .Height = 30}
042. 
043.        Dim link1 As New MyLink(node1, node4) With {.Content = "A"}
044.        Dim link2 As New MyLink(node1, node3) With {.Content = "B"}
045.        Dim link3 As New MyLink(node1, node2) With {.Content = "C"}
046.        Dim link4 As New MyLink(node2, node3) With {.Content = "D"}
047. 
048.        AddNode(node1)
049.        AddNode(node2)
050.        AddNode(node3)
051.        AddNode(node4)
052. 
053.        AddLink(link1)
054.        AddLink(link2)
055.        AddLink(link3)
056.        AddLink(link4)
057.    End Sub
058. 
059. 
060. 
061.End Class
062. 
063.Public Class CommandImpl
064.    Implements ICommand
065. 
066.    Private _command_action As Action
067.    Public Sub New(p_action As Action)
068.        _command_action = p_action
069.    End Sub
070. 
071.    Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
072.        Return True
073.    End Function
074. 
075.    Public Event CanExecuteChanged(sender As Object, e As EventArgs) Implements ICommand.CanExecuteChanged
076. 
077.    Public Sub Execute(parameter As Object) Implements ICommand.Execute
078.        _command_action()
079.    End Sub
080.End Class
081. 
082.Public Class MyBaseNode
083.    Inherits NodeViewModelBase
084. 
085.    Public Overrides Function ToString() As String
086.        Return If(Content IsNot Nothing, Content.ToString, "")
087.    End Function
088.End Class
089. 
090. 
091.Public Class MyLink
092.    Inherits LinkViewModelBase(Of MyBaseNode)
093. 
094.    Public Sub New()
095.        MyBase.New()
096.    End Sub
097. 
098.    Public Sub New(source As MyBaseNode, target As MyBaseNode)
099.        MyBase.New(source, target)
100.    End Sub
101. 
102.    Public Overrides Function ToString() As String
103.        Return If(Content IsNot Nothing, Content.ToString, "")
104.    End Function
105.End Class

 

 

4 Answers, 1 is accepted

Sort by
0
Petar Mladenov
Telerik team
answered on 06 Jun 2016, 09:48 AM
Hello Affreux,

I guess you use Path/Pencil tool to draw a shape in the Diagram. When mouse down is triggered in the Diagram, new ViewModel (in your case MyBaseNode  object is created), however it is also expected that the Shapes's Geometry, Width, Height are not prepared and calculated yet.
Could you please elaborate a bit more on your specific scenario, why do you need these properties in such early stage ? And why do you need Width/ Heights properties stored in ViewModel - this is not typical for MVVM - storing UI properties in the ViewModel.

Regards,
Petar Mladenov
Telerik
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Affreux
Top achievements
Rank 1
answered on 06 Jun 2016, 10:08 AM

I'm implementing a drawing application, where the user can draw lines, add common shapes (rectangle, circle, thick arrow, etc), and some custom databound shapes (the user adds a shape, and several times in the future I change its text and backcolor).

I need to persist this drawing between sessions.

0
Affreux
Top achievements
Rank 1
answered on 06 Jun 2016, 10:10 AM
I don't need the shapes very early, I'd be happy to have their info on MouseUp, but right now, I get nothing (they stay at width=0, height=0)
0
Petar Mladenov
Telerik team
answered on 07 Jun 2016, 03:47 PM
Hello Joel,

We can use our CustomSettingsPane SDK Sample and our HowToSerialize DataBound Diagram resources as a base for our discussion. As first step, you need to use SerializableGraphSourceBase.

 In the demo (sdk), when you draw a shape with Path/Pencil Tool , the setter of the Geometry property of the ShapeViewModel class will fire (two way binding kicks in after the AddNode from the GraphSource). In order to Serialize / Deserialize the Geometry of the Shapes. You need to:

-- case A (you drag a shape from he toolbox) The default SerializationService saves the shape from toolbox and on drop shape is deserialized. You need to attach to ItemSerializing event and save the geometry:
SerializationService.Default.ItemSerializing += DefaultSerializationService_ItemSerializing;
 
private void DefaultSerializationService_ItemSerializing(object sender, SerializationEventArgs<IDiagramItem> e)
        {
            if (e.Entity != null && e.Entity is RadDiagramShape)
            {
                var shape = e.Entity as RadDiagramShape;
                if (shape.Geometry != null)
                {
                    e.SerializationInfo["MyGeometry"] = (e.Entity as RadDiagramShape).Geometry.ToString();
                }
            }
        }
On Drop, Deserialize Node of the GraphSOurce is fired when you can restore the ViewModels's Geometry property.

    -case B: You invoke the Save method / command of the Diagram. Then the Serialize method of the SerializableGraphSource is fired so you can save the geometry of the model into the dictionary:
public override void SerializeNode(ShapeViewModel node, SerializationInfo info)
     {
         info["MyGeometry"] = node.Geometry.ToString();
         base.SerializeNode(node, info);
     }
Later on Load, Deserialize will successfully restore the ViewModel.

On a side note, we encourage you to send us a direct support ticket. This way your 24-hours response time is guaranteed.

Regards,
Petar Mladenov
Telerik
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
Diagram
Asked by
Affreux
Top achievements
Rank 1
Answers by
Petar Mladenov
Telerik team
Affreux
Top achievements
Rank 1
Share this question
or