/*
* Copyright (c) 2004, 2005 MyXaml
* All Rights Reserved
*
* Licensed under the terms of the GNU General Public License
* http://www.gnu.org/licenses/licenses.html#GPL
*/
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using MyXaml;
namespace MyXaml.MxWorkflow
{
/// <summary>
/// Assigns a value to a target property.
/// </summary>
public class Set : Process
{
protected string property;
protected string val;
/// <summary>
/// The property whose value to set. Specified as an attribute in the markup.
/// </summary>
public String Property
{
get {return property;}
set {property=value;}
}
/// <summary>
/// The value to which to set the property. Specified as an attribute in the markup.
/// </summary>
public String Value
{
get {return val;}
set {val=value;}
}
/// <summary>
/// Internal use.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "Set: "+property+"="+val;
}
/// <summary>
/// Constructor.
/// Used in the markup to instantiate a Set workflow.
/// </summary>
public Set()
{
target=String.Empty;
property=String.Empty;
}
/// <summary>
/// Internal use. Processes the Set statement.
/// </summary>
/// <param name="wfProc"></param>
public override void Invoke(MxWorkflowProcessor wfProc)
{
// Check to see if the container we are trying to set
// the property for is nested
// i.e model.container
// Modifed 24/10/2004 Michael Butler
object tempTarget=target;
if(target != null && target is string)
{
string tg = target.ToString();
if(tg[0] == '*')
{
tempTarget = this.LateBinding(tg);
}
}
if ( (tempTarget != null) && (val != null) && (property != null) )
{
// get the target type (must be specified in the markup.
Type t=tempTarget.GetType();
object[] parms=new object[] {val};
// process any late binding in the parameter.
Type[] types=ProcessParams(parms);
// get the property info for the specified property.
PropertyInfo pi=t.GetProperty(property);
if (pi != null)
{
try
{
object obj=parms[0];
// get the TypeConverter for the property type.
TypeConverter tc = TypeDescriptor.GetConverter(pi.PropertyType);
// if the value is a string...
if (obj is String)
{
// can we convert from a string to the property type
if (tc != null && tc.CanConvertFrom(typeof(string)))
{
// changed from ConvertFromString, as per CPian tditiecher, to support different culture formats
object objConv=null;
try
{
objConv = tc.ConvertFromInvariantString((string)obj);
}
catch (Exception e)
{
Trace.WriteLine("Conversion from '"+val+"' failed: "+e.Message);
}
// The Form.MainMenu property returns true for CanConvertFrom, but null when the conversion takes place!
if (objConv != null)
{
try
{
pi.SetValue(tempTarget, objConv, null);
}
catch(Exception e)
{
Trace.WriteLine("Workflow setter failed: "+e.Message);
}
}
}
}
else
{
// get the type converter for the current value object
TypeConverter valTypeConverter=TypeDescriptor.GetConverter(obj.GetType());
// can we convert to the type required by the property?
if (valTypeConverter.CanConvertTo(pi.PropertyType))
{
// if so, do the conversion
obj=valTypeConverter.ConvertTo(obj, pi.PropertyType);
}
pi.SetValue(tempTarget, obj, null);
}
}
catch(Exception e)
{
Trace.WriteLine("Invocation Exception: "+e.Message+" "+e.InnerException);
}
}
else
{
Trace.WriteLine("No property defined: "+property);
}
}
else
{
Trace.WriteLine("Set is missing the target, property, and/or value");
}
}
}
}