Saturday, February 25, 2012

Custom ControlFlow

I am trying to design a Component which can be configured by a UI. After Configuration from the Design pane the Data should be passed to the back-end of the Component.
When I look at some code samples I only see, that it's possible to pass simple data.
What I want is to put a grid on the UI and connect it to a DataTable. This is used for displaying and changing a configuration as a table.
Well, the question is: Can I pass the DataTable object to the backend-DLL as is? If so then how?
THX
Fridtjof
Can you please clarify whether you are creating a custom Task or a custom Data Flow Component, or another type of run-time object like a connection manager? The APIs are similar but not identical.

-Doug
|||From your subect I assume you mean a Task. Why can you not just create a property of your task, typed as a DataTable?|||Well I don't have any instance of the Backend Class in the Definition of the UI-Class, have I?
If I had one there would be no problem setting the DataSource of the Grid to that DataTable.
|||

You keep referring to the backend-class, do you mean the task itself, the class that inherits from Task?

If so you should have a reference to it in the UI. You need to cache it and pass it through, but otherwise there is not much point to the UI.

Review this code form one of my tasks. This is the UI class, the one that inherits from IDtsTaskUI. My form is ZipFileTaskUIForm, and has a modified constructor to accept the parameters passed through. You can see the TaskHost is cached in Initialize, and then passed to the form. This is how you get a reference to your task into the form.


public System.Windows.Forms.ContainerControl GetView()
{
return new ZipFileTaskUIForm(_taskHost, _dtsConnectionService, _dtsVariableService);
}
public void Initialize(TaskHost taskHost, IServiceProvider serviceProvider)
{
_taskHost = taskHost;

IDtsVariableService dtsVariableService = serviceProvider.GetService(typeof(IDtsVariableService)) as IDtsVariableService;
IDtsConnectionService dtsConnectionService = serviceProvider.GetService(typeof(IDtsConnectionService)) as IDtsConnectionService;
_dtsConnectionService = dtsConnectionService;
_dtsVariableService = dtsVariableService;
}


|||To your question: Yes I mean the class which inherits from Task! That's what I call Backend-Class.
Your code is from the Class which inherits from IDtsTaskUI.
The question is how can you access public members of my Backend-Class in the UI (Form).
Maybe I have to convert and cache then, because the ui is called at design-time and the Backend at runtime?
|||Your form should be invoked from the UI class (IDtsTaskUI). The sample I showed demonstrates grabbing TaskHost, and passing it through to the form. You use the TaskHost to access properies of the task itself. You cannot get direct access to the Task instance, but you should not actually need to as you have TaskHost instead.
If you have code that you wish to share between trasjk and UI classes, then make them public static. Instance members would not work anyway since you cannot get the instance.

|||In addition to the Initialize method in the UI class that comes from the IDtsXxxUI interface, I would be inclined to write an Initialize method of my own in my Windows Forms class and pass along a reference to my task or other object, so I can easily read its current property values to set initial control states and values, then update its properties from the controls when the user closes the form.

So Task passes reference to itself in calling Initialize in Task UI class, and Task UI class passes reference to task in calling custom Initialize method in Task UI Form class.

-Doug
|||

I am also facing same problem. When i explored i came to know that there was two method SaveToXML() and LoadXML() of IDTSPersist90 interface to handle this type of scenerio. But i could not able to raise these methods. you can transfer either string or interger...etc, but if you want to transfer some custom object i think you have to preserve the same in xml and retrieve it when ever needed

...Karun

|||

As I understand the issue, bearing in mind this thread crossed several, none of which matched the title that well, but you are writing a task and have a complex type that you need to persist. All persistance is through XML, and for complex stuff you need to implement IDTSPersist90 yourself. The methods are never called by you, they are called by the designer. You fill in the code to save and load the values to and from the XML document provided, and you can choose how you store the information in the XML.

For objects, I found the easiest way to to serialize them, and actually binary serialization at that. This snippet gives me a string that I can easily store in an xml element for the property.

public static string SerializeObject(object graph) { BinaryFormatter formatter1 = new BinaryFormatter(); MemoryStream stream1 = new MemoryStream(); formatter1.Serialize(stream1, graph); string text1 = Convert.ToBase64String(stream1.GetBuffer()); stream1.Close(); return text1; }

Another alternative is to use reflection to read an object's properties, and then build up an XML node that represents this. Here is an example of creating a new element with sub elements for each property-

public static XmlElement AddXmlObjectProperties(XmlElement parentElement, string propertyName, object propertyObject) { XmlElement element1 = XMLPersistanceHelper.AddXmlElement(parentElement, propertyName); Type type1 = propertyObject.GetType(); foreach (PropertyInfo info1 in type1.GetProperties()) { Type type2 = info1.PropertyType; string text1 = type2.Name; object obj1 = info1.GetValue(propertyObject, null); if (type2.IsEnum) { obj1 = Convert.ToInt32(info1.GetValue(propertyObject, null)); } if (obj1 != null) { XmlElement element2 = XMLPersistanceHelper.AddXmlElement(element1, "Property", obj1.ToString()); XMLPersistanceHelper.AddXmlAttribute(element2, "Name", info1.Name); XMLPersistanceHelper.AddXmlAttribute(element2, "Type", text1); } } return element1; }

No comments:

Post a Comment