Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Access Object Within Node.Tag (Read 5729 times)
Megan1717
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 39
Joined: Jun 20th, 2016
Access Object Within Node.Tag
Jul 1st, 2016 at 3:54pm
Print Post  
Hello,

I need to access the object, we'll say of type "Student", from the node's tag on server-side (controller method). Sending the diagram through AJAX to the controller method works fine, and I can manipulate other properties of that diagram's nodes, such as tooltip, without a problem. However, when I try to explicitly cast the node.Tag to Student, I get an internal server error. The node's tag was originally set as an object reference with type "Student." Is there a way to get that data back and be able to work with it? In cases where I just send a node's tag over using AJAX and do some logic, it works fine, but in this case I need to basically send the whole diagram to do my logic.

Many thanks in advance!
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Access Object Within Node.Tag
Reply #1 - Jul 1st, 2016 at 5:36pm
Print Post  
Hi,

I think you must create a JavaScriptConverter class for custom types you assign to Tag, both to make them accessible as JavaScript objects on client side and to preserve them after postback. Here's one of the diagram's converters you could use as a template -

Code
Select All
/// <summary>
/// Serializes SizeF instances.
/// </summary>
internal class SizeConverter : JavaScriptConverter
{
    /// <summary>
    /// SupportedTypes override.
    /// </summary>
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new List<Type>(new Type[] { typeof(System.Drawing.SizeF) });
        }
    }

    /// <summary>
    /// Deserialize override.
    /// </summary>
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        System.Drawing.SizeF size = new System.Drawing.SizeF();
        size.Width = ((IConvertible)dictionary["width"]).ToSingle(CultureInfo.InvariantCulture);
        size.Height = ((IConvertible)dictionary["height"]).ToSingle(CultureInfo.InvariantCulture);
        return size;
    }

    /// <summary>
    /// Serialize override.
    /// </summary>
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        IDictionary<string, object> json = new Dictionary<string, object>();
        System.Drawing.SizeF size = (System.Drawing.SizeF)obj;
        json.Add("isEmpty", size.IsEmpty);
        json.Add("width", size.Width);
        json.Add("height", size.Height);

        return json;
    }
} 



You must pass your converters to DiagramView.RegisterConverters methods before serializing to or deserializing from JSON.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Megan1717
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 39
Joined: Jun 20th, 2016
Re: Access Object Within Node.Tag
Reply #2 - Jul 1st, 2016 at 7:34pm
Print Post  
Hello,

Thank you for the information and quick response. I did create a converter class that inherits from JavaScriptConverter and added it to the diagram view:

Code (C++)
Select All
view.RegisterConverters(new JavaScriptConverter[] { new StudentConverter()}); 



I'm stuck on what to do in the controller in order to use the converter and create Student objects out of the nodes' Tags. This is what I have so far:

Code (C++)
Select All
  public JsonResult SelectedStudent(string json, int num)
        {
            DiagramView view = DiagramView.FromJson(json);
            Diagram diagram = view.Diagram;

            foreach (var node in diagram.Nodes)
            {
                //Only look at Student nodes
                if(node is Student)
                {
                    ShapeNode selectedStudent = (ShapeNode)node;
                    //Node.Tag.Id should represent the student's id
                    if(node.Tag.Id == num)
                    {
                        //do stuff
                    }

                }

            }
            return Json(new { success = DiagramView.ToJson(view) });
        } 



Because I'm getting the number from another 3rd party control, I cannot just send the node. I must match that number to the number in the node's tag.

Thanks again.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Access Object Within Node.Tag
Reply #3 - Jul 1st, 2016 at 7:47pm
Print Post  
Hi,

You should register the converters on same instance that loads or saves JSON, try changing your code to this -

Code
Select All
var view = new DiagramView();
view.RegisterConverters(...);
view.LoadFromJson(json); 



Later, node will never be student but node.Tag instead, so replace the if(node is Student) check with this -

Code
Select All
var student = node.Tag as Student;
if (student != null && student.Id == num)
{
   // .... 



Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Megan1717
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 39
Joined: Jun 20th, 2016
Re: Access Object Within Node.Tag
Reply #4 - Jul 5th, 2016 at 2:35pm
Print Post  
Thanks, again for your advice. So, I spent some time over the weekend looking at JavaScript Converter classes and experimenting with other ways to get the nodes' tags after   sending them through an AJAX call to a controller method. Another thing I found was that even if I just wanted to access a node's tag in the controller method without trying to use it as a specific object type, it comes up null even though I can see the appropriate tag data in the json parameter when debugging. How can I get to a diagram's nodes' tags in the controller method and have them not be null? I am guessing this is related to how Json works.

Thanks in advance for your time and patience.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Access Object Within Node.Tag
Reply #5 - Jul 5th, 2016 at 6:57pm
Print Post  
Are you initially setting node.Tag on client side?
  
Back to top
 
IP Logged
 
Megan1717
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 39
Joined: Jun 20th, 2016
Re: Access Object Within Node.Tag
Reply #6 - Jul 5th, 2016 at 7:34pm
Print Post  
Hello,

Node.Tag is set in the view using C#/Razor, because it needs to hold "Student" data. Please correct me if I am wrong, but I cannot set the node.tag in client side to a Student object, since JavaScript won't recognize this object type, right? However, I need to be able to get that Student data back from the tags in a controller method. For instance, if the user clicks a node representing "Bob," I need to be able to access Bob's properties as a student object in the controller method and do whatever magic I need to, if that makes sense.

Thanks for your continued patience.

  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Access Object Within Node.Tag
Reply #7 - Jul 6th, 2016 at 10:17am
Print Post  
Quote:
Please correct me if I am wrong, but I cannot set the node.tag in client side to a Student object, since JavaScript won't recognize this object type, right


That might be the problem - the diagram loads Json sent by these converters by first instantiating JavaScript classes by calling 'new' operator, so you might need a Student class in JavaScript too (similar to how the library defines ShapeNode both as C# and JS classes). Our developer will check if this can be done to work with anonymous objects so you define classes only in C#. We'll upload an example later.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Access Object Within Node.Tag
Reply #8 - Jul 7th, 2016 at 7:28am
Print Post  
It turns out it works with anonymous objects, but you must also call the RegisterItemType method so the control knows what .NET object to create from the type field stored in Json -

Code
Select All
public JsonResult Test(string json)
{
   DiagramView view = new DiagramView();
   view.RegisterItemType(typeof(Student), "Student", "", 0);
   view.RegisterConverters(new JavaScriptConverter[] { new StudentConverter() });
   view.LoadFromJson(json);

   return Json(new { success = view.SaveToJson() });
}

/// <summary>
/// Serializes Student instances.
/// </summary>
internal class StudentConverter : JavaScriptConverter
{
 /// <summary>
 /// SupportedTypes override.
 /// </summary>
 public override IEnumerable<Type> SupportedTypes
 {
  get
  {
   return new List<Type>(new Type[] { typeof(Student), typeof(IDictionary<string, object>) });
  }
 }

 /// <summary>
 /// Deserialize override.
 /// </summary>
 public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
 {
  Student b = new Student();
  b.Name = dictionary["name"].ToString();
  return b;
 }

 /// <summary>
 /// Serialize override.
 /// </summary>
 public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
 {
  IDictionary<string, object> json = new Dictionary<string, object>();
  Student b = (Student)obj;
  json.Add("name", b.Name);

  return json;
 }
}

public class Student
{
 public Student() { }
 public Student(string name)
 {
  Name = name;
 }
 public string Name
 { get; set; }
} 



This should preserve Student tags between post-backs, and you will also be able to access node.tag.name from client side JavaScript code.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Megan1717
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 39
Joined: Jun 20th, 2016
Re: Access Object Within Node.Tag
Reply #9 - Jul 7th, 2016 at 3:15pm
Print Post  
Awesome! I will give this a try. Thank you so much for your time, effort, and patience! Very much appreciated.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint