2

Closed

EvaluateParameter and special values

description

Hi!
I would like a parameter to be bound to a textBox's Text property. In such case, I don't see any way for CM to distinguish if the parameter is already evaluated or not.
E.g.: if the user types special values, such as "$datacontext", the parameter's value is interpreted.

To overcome this problem, the EvaluateParameter method should probably changed to accept an entire Caliburn.Micro.Parameter as input (not only its properties). This would allow implementors of EvaluateParameter to add custom logic, such as to check for other properties (coming from object derived from Caliburn.Micro.Parameter).

file attachments

Closed Sep 16, 2013 at 2:04 AM by EisenbergEffect
We aren't going to change this behavior for now. When we start working on v2.0, we can then make some breaking changes and do some re-design. Please re-submit a new issue at that time with a proposed design change explanation.

comments

BladeWise wrote Apr 2, 2013 at 8:27 AM

Are you referring to the short syntax? If so, note that such syntax is just a convenient way to define simple actions, and you can still use the full syntax to provide whatever logic you need.

Moreover, short syntax is customizable: see this post regarding actions short-syntax customization. There is source code to allow full binding short-syntax support and, if interested, function evaluation at parameter level.

starnutoditopo wrote Apr 2, 2013 at 9:38 AM

Yes, I have been looking at the post you suggested. My point is that the EvaluateParemeter function only takes 3 parameters as input: string, Type, ActionExecutionContext. What if I want the evaluation to depend on some other property? e.g.: I would like to create a custom parameter, that has a property specifying if the value should be interpreted using some syntax, or if it is effectively a finished value. In my application it is very useful to take advantage of special values, but sometimes I don't want my parameter to be interpreted. At the moment, when EvaluateParameter receives a string, let's say "$datacontext", it cannot distinguish if if has been specified by the programmer, in XAML, and it should be interpreted, of if it has been passed at runtime.

Let me explain using an example.

case 1:
<cm:Parameter Value="$datacontext" />
here an object is passed as parameter: the view's datacontext. Fine.

case 2:
<cm:Parameter Value="{Binding ElementName=textboxFind, Path=Text}" />
in this case, the parameter is evaluated to the string contained in the Text property of a textbox called textboxFind. Generally fine. But what if the user types: "$datacontext"? The parameter is evaluated as in case 1. This is wrong.

So, how is it possible to distinguish this case, in which the the value should not be interpreted, from other cases, in which that functionality is useful?

Thanks!

BladeWise wrote Apr 2, 2013 at 10:39 AM

I can see imagine a couple of different approaches to solve the problem:
  1. Use an additional parameter to the action, and modify the action (function) behaviour depending on the additional paramter result
  2. Use the full-blown syntax and use a multibinding to determine what is the correct value of the parameter (the result of the binding should be either the $datacontext value or a specific value used to define if the function should ignore the parameter).
On a side note: as long as I can tell, the usage of 'special values' (e.g. $datacontext) is only interpreted using the short syntax, not the full syntax. Parameters substitution is a functionality offered by the Parser used by Message.Attach, and is never used when specifying a Parameter Value through a binding. If you check the Parameter class, you can notice that there is no reference to the code that performs substitution.
So, in your example, in case the user writes down '$datacontext', such a string will be directly passed to the function itself, and will not be substituted with the actual DataContext.

tibel wrote Apr 9, 2013 at 6:23 AM

SpecialValues.TryGetValue() is used in MessageBinder and ViewModelBinder, too.
Not sure why this is the case, but it would explain the described behavior.

BladeWise wrote Apr 9, 2013 at 11:17 AM

In the ViewModelBinder.BindActions, the special value is 'guessed' depending on the view-model method signature (e.g. if a parameter is called $dataContext, at runtime the actual DataContext is used as a parameter value), and this behavior should not present any problem, since the method should be called in a view-first scenario.

I think that the real issue lies in the ActionMessage.InvokeAction: special values are re-evaluated at invocation time, depending on the Parameter.Value. In such a case, if the parameter is databound to a TextBox, it is possible for the user to provide special values. In my opinion, special values substitution should happen when the Parameter is defined (e.g. Using $dataContext should set the Parameter.Value with a binding to the actual DataContext), and invocation should only use the actual Parameter.Value. Unfortunally, to allow such a thing, the actual ActionExecutionContext should be some-how bindable... I fear that a deeper discussion is needed...

tibel wrote Sep 13, 2013 at 7:41 PM

Attached sample