Create an array in windows workflow foundation - workflow-foundation-4

Is it possible to create a new array in windows workflow? More specifically, in the designer.
I've created a variable of System.Int32[], but when I use it I get a NullReferenceException.
I've tried New Int32(5), and various permutations of Dim - nothing I have tried has worked.
I was able to create the array and pass it as an in/out parameter - this works, however the workflow will need to determine the actual size of the array.

To create and instantiate an array, you have to set a default value to your variable with New Int32(FOO SIZE){} or use an Assign activity to instantiate it with the correct size in runtime
You can also use List(Of T) or any other .NET collection structure to achieve dynamic size.
Note that the value must be the right part of a set expression. So, you can google how to do it in VB.NET and you will be fine.

I assume that if you are creating the array in the designer, as you stated, it is either a workflow variable or a workflow argument. The "WF" way to do this would be to use the "Default Value" column under the "Variables" and/or "Arguments" tab.
If it is an argument then the Default Value column only works if the Direction is "In". If your argument is a property, or an Out, or In/Out direction then you would have to use the method mentioned by Davi.
If you are creating it under the "Variables" tag then using the Default value column would be the more built-in approach. The syntax in the default column would be the same syntax mentioned by Davi: New Int32(FOO SIZE) {}

Related

Can you map a fixed value using the standard BizTalk mapper

Normally, I create my BizTalk mappings in the XSL. Today I was playing around with the mapper but I am failing to do the most basic thing and googling it fails me (I find unrelated questions or the basic way to do it in XSL)
The question is simple though, I want to use the BizTalk mapper (btm file) to map one element to another and fill a second element with a fixed value.
Looking at the functoids, I have a date functoid which gets today's date but nothing to just type some text and map it.
Am I missing something very obvious?
The "built in" way to do this is to set the Value property on the destination node in the map (you can also use this property to desginate that an empty node should be created for this destination node). Unfortunately, this method offers no visual representation that the node is being set this way, except that it will prevent you from linking other nodes/functoids to that destination node. This may lead future devs (or your future self) to think the node isn't being set, or be confused as to why it's being set when it has no inputs.
To get around this, I've frequently used either a String Concatenate functoid (with the fixed value as the only parameter, manually typed in) or a Value Mapping functoid (set "true" as the first parameter and the fixed value as the second parameter). This offers a few benefits:
Visually shows that node is being set by the map
Allows you to set a meaningful label and/or comment on the functoid to denote why you're setting that value.

Multiple "default" properties/methods in a VB6 class?

I am trying to make a replacement VB6 class for the Scripting.Dictionary class from SCRRUN.DLL. Scripting.Dictionary has (among other things) a "Keys" method that returns an array of keys, and a read/write "Item" property that returns the item associated with a key. I am confused about this, because both of them seem to be defaults for the class. That is:
For Each X In MyDict
Is equivalent to:
For Each X In MyDict.Keys
Which to me implies that "Keys" is the default operation for the class, but:
MyDict("MyKey") = "MyValue"
MsgBox MyDict("MyKey")
Is equivalent to:
MyDict.Item("MyKey") = "MyValue"
MsgBox MyDict.Item("MyKey")
Which to me implies that "Item" is the default operation for the class.
I've never before created a VB6 class that had a default operation, so upon realizing this, I thought perhaps I could define multiple default operations as long as they all have different signatures, which they do: Keys is nullary, the Item getter takes a Variant, and the Item setter takes two Variants. But this doesn't seem to be allowed: When I use "Tools/Procedure Attributes" to set the Keys function to be the default, and then I use it to set the Item property to be the default, the IDE complains that a default has already been set.
So I think I'm misunderstanding something fundamental here. What is going on in the Scripting.Dictionary object that makes it able to act as if "Keys" is the default in some contexts, but as if "Item" is the default in others? And whatever it is, can I accomplish the same thing in VB6?
OK, answering my own question: I haven't tried this yet, but I gather that "Item" should be made the default, and that I should add an entirely new function called "NewEnum" that looks something like the following (slightly modified from an example in Francesco Balena's "Programming Microsoft Visual Basic 6.0" book):
Public Function NewEnum() As IUnknown
Set NewEnum = m_Keys.[_NewEnum]
End Function
(where "m_Keys" is a Collection containing the keys), and then use Tools/Procedure Attributes to hide NewEnum and to set its ProcID to -4.
What you are observing is the difference between the default member and a collection enumerator. A COM object (including VB6 classes) can have both.
You can identify the default property of a class by looking in the Object Browser for the tiny blue globe or the words "default member of" in the description (see Contents of the Object Browser). The Object Browser will not identify an enumerator method, but if you look at the class's interface definition using OLE View or TypeLib Browser (free but registration required) it's DispId will be 0xfffffffc or -4.
In your own class, you can mark the default property by setting the Procedure ID to "(default)" in the Procedure Attributes dialog (see Making a Property or Method the Default). You already listed the steps for setting up the collection enumerator in your own answer, but you can find this listed as well in the Programmer's Guide topic Creating Your Own Collection Class: The House of Bricks.
Scripting.Dictionary has a dirty secret:
It does not handle enumeration at all, it returns big ugly Variant arrays and your For Each loops iterate over those.
This is one of the reasons why a Dictionary can actually be far less efficient than a standard VB6 Collection.

Asp.NET MVC Model Binding Not Picking Up A Value for List Item

I've got an object with a list defined inside it which points to a type that can be inherited. From what I understand MVC's default model binder will always instance the base type when reading data back in to this array from a form so by default I will have a list of base types.
So I need to use my own model binder and override CreateModel to instance a specific type (say from a hidden field). However when I do this and use
bindingContext.ValueProvider.GetValue("ModelType")
it always returns null even though through using fiddler I can see that form value Settings[0].ModelType contains my objects type and I need this value in CreateModel to instance the correct type.
Solved it. If your array objects need to be typed based on each item you need to use the following call to get "into" the array item
bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType")
I'm not sure if this is the standard way to do it. If anyone has any better suggestions feel free to add them

How to store object types and create objects using that information only

I would like to store MetaObjects in a list like this:
myList = QList<QMetaObject>();
myList->append(MyClass::staticMetaObject);
myList->append(MyOtherClass::staticMetaObject);
I want to keep track of these object through out the application but I don't wish to allocate them just yet. By adding some information in my classes I will be able to use the MetaObject function "classInfo(int).value()". I use this when I store them in a QListWidget. When a row in the QListWidget is pressed I would like to be able to create an object of that specific kind that is stored in the list.
(Also have to add that all the classes dervies from the same baseclass)
This sample code describes a bit of what I want to do, except in his example, you add the classes as you go along.
http://lists.qt.nokia.com/pipermail/qt-interest/2012-January/037204.html
I read through the manual and when I try things like:
MyBaseClass *test = qobject_cast<MyBaseClass*>myList->at(i).newInstance();
The project compiles but when I try to print the "test" object its null. What am I doing wrong? And is this the best way of doing this?
Was also looking at MetaType, but where would i be able to store, for example a string for the menus if I'm not allowed to create the object? Would this be a nicer solution if I have a static function that returns a string?
Edit:
I now changed so the constructors are Q_INVOKABLE which solved the problem where "test == null".
But what are the downside of this solution? Should I just use a object factory (the old fashion way with a switch case)?

Is a DropShadowFilter mutable in Flex 3.5?

I have a dropfilter defined using some bindable variables as parameters.
<mx:filters>
<mx:DropShadowFilter id="torinofilter" distance="0" color="{dropShadowColor}"
blurX="{dropBlur}" blurY="{dropBlur}" strength="8" quality="2"
alpha="{dropAlpha}"/>
</mx:filters>
I would like to update the filter in a method call like this:
this.dropShadowColor = <new color>
this.dropBlur = 15.0;
this.dropAlpha = 0.8;
Upon tracing both this.dropShadowColor and torinofilter.color, I see they have updated to the new color, but the color of the dropfilter doesnt change.
I would prefer not to create a new filter because then I get issues with swapChildren.
Properties of filters cannot be modified like this.
To modify an existing filter object, you must use the technique of modifying a copy of the filters array:
Assign the value of the filters array to a temporary array, such as one named myFilters.
Modify the property by using the temporary array, myFilters. For example, to set the quality property of the first filter in the array, you could use the following code: myFilters[0].quality = 1;
Assign the value of the temporary array to the filters array.
Basically when you read filters array of a DisplayObject, flash returns a copy of the array, not the live filters array. Pushing a new filter or updating existing filters will only modify the copy, not the original; you have to assign it back to the array to reflect the changes.
Do this from actionscript instead of mxml.
I would prefer not to create a new filter because then I get issues with swapChildren.
swapChildren applies only to display objects (UIComponents in case of flex containers).

Resources