Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Problem with deserialization (Read 13402 times)
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Problem with deserialization
Nov 10th, 2011 at 6:44pm
Print Post  
Stoyo, this is a virtual keybaord code i trying to add to my diagram.


I add to the diagram my keabord in this way and work correctly.
keybaord perform without any problem.
[code]
var keyb = new BensOnScreenKeyboard(this);
var node = new DiagramNodeAdapter(form, keyb);
node.Bounds = new Rect(e.MousePosition, new Size(450, 190));

form.Nodes.Add(node);
node.HandlesStyle = HandlesStyle.Custom;
node.Constraints.MinWidth = 450;
node.Constraints.MinHeight = 190;
node.Constraints.MaxWidth = 1024;
node.Constraints.KeepRatio = true;
node.Selected = true;

[/code]


My problem start when i save the diagram, and try load i have error:


System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
Source=window6
StackTrace:

at window6.Window6.form_DeserializeControl(Object sender, ControlNodeEventArgs e) in Window6.xaml.cs:line 3140

at MindFusion.Diagramming.Wpf.Diagram.OnDeserializeControl(ControlNodeEventArgs e)

at MindFusion.Diagramming.Wpf.Diagram.BR(DiagramNodeAdapter A, XmlElement B, XmlPersistContext C)

at MindFusion.Diagramming.Wpf.DiagramNodeAdapter.LoadFromXml(XmlElement xmlElement, XmlPersistContext context)

at MindFusion.Diagramming.Wpf.XmlPersistContext.R(XmlElement A)

at MindFusion.Diagramming.Wpf.Diagram.LoadFromXml(XmlDocument document)
InnerException:


[code]
private void form_DeserializeControl(object sender, ControlNodeEventArgs e)

{


string typeName = e.XmlElement.GetAttribute("Type");


var type = System.Type.GetType(typeName);


var constructor = type.GetConstructor(System.Type.EmptyTypes);


var instance = constructor.Invoke(null) as UIElement;


var srz = instance as ISerializable;


srz.Load(e.XmlElement, e.Context);


e.Node.Control = instance;


e.Handled = true;



}
[/code]


the line of error is is this: var instance = constructor.Invoke(null) as UIElement;




This is the complete code of my custom component, this keyboard send keystrokes to external aplications form my appz.
Have soem sugestion how make this work without broken my code?


continue.........
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #1 - Nov 10th, 2011 at 6:44pm
Print Post  
Code
Select All
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using MindFusion.Diagramming.Wpf;
using System.Xml;

namespace window6
{

    public partial class BensOnScreenKeyboard : UserControl, ISerializable, ICloneable
    {
	  [DllImport("user32.dll")]
	  public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

	  [DllImport("user32.dll", SetLastError = true)]
	  public static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);


	  /// <summary>
	  /// Get or set this controls parent window
	  /// </summary>
	  private Window parentWindow;

	  /// <summary>
	  /// Get or set this controls element to focus on
	  /// </summary>
	  private IInputElement focusedInputElement;

	  /// <summary>
	  /// Create a new BensOnScreenKeyboard
	  /// </summary>
	  /// <param name="parent">The parent window that calls this control</param>
	  public BensOnScreenKeyboard(Window parent)
	  {
		InitializeComponent();
		DataContext = this;
		// set parent
		this.parentWindow = parent;
		// setup this control
		this.setupKeyboardControl();
	  }

	  /// <summary>
	  /// Create a new SingerOnScreenKeyboard
	  /// </summary>
	  /// <param name="parent">A specified element to hold this controls focus</param>
	  public BensOnScreenKeyboard(IInputElement elementToFocusOn)
	  {
		InitializeComponent();
		DataContext = this;
		// set focus
		this.focusedInputElement = elementToFocusOn;
		// setup this control
		this.setupKeyboardControl();
	  }

	  /// <summary>
	  /// Setup the keyboard control
	  /// </summary>
	  private void setupKeyboardControl()
	  {
		InitializeComponent();
		DataContext = this;
	  }


	  public object Clone()
	  {
		var clone = new BensOnScreenKeyboard(this);
		clone.OpacityGlobal = this.OpacityGlobal;
		return clone;
	  }


	  static public DependencyProperty OpacityGlobalProperty = DependencyProperty.Register("OpacityGlobal", typeof(Double), typeof(BensOnScreenKeyboard));
	  public double OpacityGlobal
	  {
		get { return (double)GetValue(OpacityGlobalProperty); }
		set { SetValue(OpacityGlobalProperty, value); }
	  }


	  private void UserControl_Loaded(object sender, RoutedEventArgs e)
	  {
		// if we have specified a parent
		if (this.parentWindow != null)
		{
		    // Get this window's handle
		    IntPtr HWND = new WindowInteropHelper(this.parentWindow).Handle;
		    // style of window?
		    int GWL_EXSTYLE = (-20);
		    // get - retrieves information about a specified window
		    GetWindowLong(HWND, GWL_EXSTYLE);
		    // set - changes the attribute of a specified window - I think this stops it being focused on
		    SetWindowLong(HWND, GWL_EXSTYLE, (IntPtr)(0x8000000));
		}
	  }


	  private void fondo1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
	  {
		 // if a focusable element has been specified
		if (this.focusedInputElement != null)
		{
		    // set keyboard focus
		    Keyboard.Focus(this.focusedInputElement);
		    // set normal focus
		    this.focusedInputElement.Focus();
		}
		// send key to simulate key press
		System.Windows.Forms.SendKeys.SendWait("x");
		}



	  public void Save(XmlElement element, XmlPersistContext cfill)
	  {
		cfill.WriteDouble(OpacityGlobal, "OpacityGlobal", element);
	  }

	  public void Load(XmlElement element, XmlPersistContext cfill)
	  {
	     OpacityGlobal = cfill.ReadDouble("OpacityGlobal", element);
	  }




    }
}

 

  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #2 - Nov 11th, 2011 at 2:53am
Print Post  
I really apreciate if can showme how correct the code for make the code non stop work, and can be deserialized.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #3 - Nov 11th, 2011 at 8:27am
Print Post  
I suppose you should trace with the debugger through the DeserializeControl code to see what exactly is null. If you post the Serialize handler, I might be able to spot the problem if its due to omitted or differently named elements.
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #4 - Nov 11th, 2011 at 10:55am
Print Post  
I dont know what information and how send.
I uplaod a simple exaple wource code, is very little and you can see the bug.

All what you have to do is, load in the diagram component  called keyboard.

Then save, ten try load and you see.

http://www.gigasize.com/get/tqdp1515vcf

In this link i uploaded the file example, for downlaod check the section called
FREE member download

Hoppe you cna helpme with thsiim 100% stuck on thsi for one of more week.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #5 - Nov 11th, 2011 at 11:42am
Print Post  
The download link didn't work for me:

Warning: parse_ini_file(mime_types.ini) [function.parse-ini-file]: failed to open stream: No such file or directory in /var/www/www.gigasize.com/mimetypehandler.class.php on line 27

Warning: require_once(lib/inc_getserver.php) [function.require-once]: failed to open stream: No such file or directory in /var/www/www.gigasize.com/getcgi.php on line 448

Fatal error: require_once() [function.require]: Failed opening required 'lib/inc_getserver.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/www.gigasize.com/getcgi.php on line 448

You could email the project to me using the mail icon on the left.
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #6 - Nov 11th, 2011 at 12:03pm
Print Post  
LOL awesome.

Project sended by mail
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #7 - Nov 11th, 2011 at 12:35pm
Print Post  
Anyway stoyo, all what you need is create a new user control.
And paste this code inside the new user control:
You cna create ndoe with thsi, and same, but when try load, you can see the problem.

Code
Select All
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using MindFusion.Diagramming.Wpf;
using System.Xml;

namespace window6
{

    public partial class BensOnScreenKeyboard : UserControl, ISerializable, ICloneable
    {
  [DllImport("user32.dll")]
  public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

  [DllImport("user32.dll", SetLastError = true)]
  public static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);


  /// <summary>
  /// Get or set this controls parent window
  /// </summary>
  private Window parentWindow;

  /// <summary>
  /// Get or set this controls element to focus on
  /// </summary>
  private IInputElement focusedInputElement;

  /// <summary>
  /// Create a new BensOnScreenKeyboard
  /// </summary>
  /// <param name="parent">The parent window that calls this control</param>
  public BensOnScreenKeyboard(Window parent)
  {
// set parent
this.parentWindow = parent;
// setup this control
this.setupKeyboardControl();
  }

  /// <summary>
  /// Create a new SingerOnScreenKeyboard
  /// </summary>
  /// <param name="parent">A specified element to hold this controls focus</param>
  public BensOnScreenKeyboard(IInputElement elementToFocusOn)
  {
// set focus
this.focusedInputElement = elementToFocusOn;
// setup this control
this.setupKeyboardControl();
  }

  /// <summary>
  /// Setup the keyboard control
  /// </summary>
  private void setupKeyboardControl()
  {
InitializeComponent();
DataContext = this;
  }


  public object Clone()
  {
var clone = new BensOnScreenKeyboard(this);
clone.OpacityGlobal = this.OpacityGlobal;
return clone;
  }


  static public DependencyProperty OpacityGlobalProperty = DependencyProperty.Register("OpacityGlobal", typeof(Double), typeof(BensOnScreenKeyboard));
  public double OpacityGlobal
  {
get { return (double)GetValue(OpacityGlobalProperty); }
set { SetValue(OpacityGlobalProperty, value); }
  }


  private void UserControl_Loaded(object sender, RoutedEventArgs e)
  {
// if we have specified a parent
if (this.parentWindow != null)
{
    // Get this window's handle
    IntPtr HWND = new WindowInteropHelper(this.parentWindow).Handle;
    // style of window?
    int GWL_EXSTYLE = (-20);
    // get - retrieves information about a specified window
    GetWindowLong(HWND, GWL_EXSTYLE);
    // set - changes the attribute of a specified window - I think this stops it being focused on
    SetWindowLong(HWND, GWL_EXSTYLE, (IntPtr)(0x8000000));
}
  }




  public void Save(XmlElement element, XmlPersistContext cfill)
  {
cfill.WriteDouble(OpacityGlobal, "OpacityGlobal", element);
  }

  public void Load(XmlElement element, XmlPersistContext cfill)
  {
     OpacityGlobal = cfill.ReadDouble("OpacityGlobal", element);
  }




    }
}
 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #8 - Nov 11th, 2011 at 2:15pm
Print Post  
Hi,

There aren't any SerializeControl and DeserializeControl handlers in the project you sent me? In any case, from the code you posted above and this from the email

Quote:
I think is a problem with constructor, not really clear.


it seems your guess is correct, the reflection code you are using will work only with a no-arguments constructor. In this case the keyboard constructors take either Window or IInputElement arguments, which the Invoke reflection method can't fill in for you. Instead, you should handle the Deserialize event like this to create an instance successfully:

Code
Select All
var instance = new BensOnScreenKeyboard(windowInstance);
...
e.Node.Control = instance;
e.Handled = true; 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #9 - Nov 11th, 2011 at 2:47pm
Print Post  
"you should handle the Deserialize event like this to create an instance successfully"

Sotyo im very confused.

Serialize:

Code
Select All
private void form_SerializeControl(object sender, ControlNodeEventArgs e)
	  {
		var srz = e.Node.Control as ISerializable;
		if (srz != null)
		{
		    e.Handled = true;
		    e.XmlElement.SetAttribute("Type", e.Node.UIElement.GetType().FullName);
		    srz.Save(e.XmlElement, e.Context);
		}
	  }
 




deserialize
Code
Select All
 private void form_DeserializeControl(object sender, ControlNodeEventArgs e)
	  {
		string typeName = e.XmlElement.GetAttribute("Type");
		var type = System.Type.GetType(typeName);
		var constructor = type.GetConstructor(System.Type.EmptyTypes);
		var instance = constructor.Invoke(null) as UIElement;
		var srz = instance as ISerializable;
		srz.Load(e.XmlElement, e.Context);
		e.Node.Control = instance;
		e.Handled = true;

	  }

 




How should look my deserialized?

This keyboard no is the only one custom component i use, but is the only oen wth i have problem.

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #10 - Nov 11th, 2011 at 2:50pm
Print Post  
Remove these two lines from the deserialize handler:

var constructor = type.GetConstructor(System.Type.EmptyTypes);
var instance = constructor.Invoke(null) as UIElement;

they don't work because you don't have a constructor without parameters, and add this line instead:

var instance = new BensOnScreenKeyboard(windowInstance);

where the windowInstance is what you usually pass to the keyboard constructor.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #11 - Nov 11th, 2011 at 2:57pm
Print Post  
var instance = new BensOnScreenKeyboard(this);


Keybaord is only one of multiple custom components, if i change the code, in this way all the other custom components, cant be deserialized, lol
Im loosed now jajaja

So my question is,

How make the keyboard be deserialized and the others  custom UserControl too?

With the desrialize code i used all the others work but not keyboard.
The change you suggest work only for keyboard.

LOL thankyou for your support, specially now when i are ultra confused jajaj
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #12 - Nov 11th, 2011 at 3:22pm
Print Post  
Either add a BensOnScreenKeyboard constructor that does not take parameters, or add a special case for the keyboard:

if (typeName.Contains("BensOnScreenKeyboard"))
{
     // create directly
}
else
{
     // create through reflection
}
  
Back to top
 
IP Logged
 
PDM.
Senior Member
****
Offline


I love YaBB 1G - SP1!

Posts: 256
Joined: Dec 2nd, 2010
Re: Problem with deserialization
Reply #13 - Nov 11th, 2011 at 3:44pm
Print Post  

Oh my god, at this point probably you want killme jajaj
I cant make thsi work, please can correct my code for have this working.
Is one of the last things i need fr finaly finish this large project.
Please!!

var instance = new BensOnScreenKeyboard(this); 

Code
Select All
private void form_DeserializeControl(object sender, ControlNodeEventArgs e)
  {
string typeName = e.XmlElement.GetAttribute("Type");
var type = System.Type.GetType(typeName);
var constructor = type.GetConstructor(System.Type.EmptyTypes);
var instance = constructor.Invoke(null) as UIElement;
var srz = instance as ISerializable;
srz.Load(e.XmlElement, e.Context);
e.Node.Control = instance;
e.Handled = true;

  }
 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Problem with deserialization
Reply #14 - Nov 11th, 2011 at 5:05pm
Print Post  
It should look like this:

Code
Select All
private void form_DeserializeControl(object sender, ControlNodeEventArgs e)
{
	string typeName = e.XmlElement.GetAttribute("Type");
	UIElement instance = null;
	if (typeName.Contains("BensOnScreenKeyboard"))
	{
		// create directly
		instance = new BensOnScreenKeyboard(this);
	}
	else
	{
		// create through reflection
		var type = System.Type.GetType(typeName);
		var constructor = type.GetConstructor(System.Type.EmptyTypes);
		instance = constructor.Invoke(null) as UIElement;
	}

	var srz = instance as ISerializable;
	srz.Load(e.XmlElement, e.Context);
	e.Node.Control = instance;
	e.Handled = true;
} 

  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint