I know there are many times that it would be nice to give the user the ability to enter an equation in a TextBox instead of letting the user calculate the value before entering it. I have
worked on projects that have implemented this functionality.
I was working on a value converter that would allow the binding to a calculated value. This got me searching the internet to see what
Eval() function. As I was working on this,
I suddenly realized that I could actually do things in the opposite way, and get a value converter that would evaluate a string to return a calculated
value to the binding element. It actually ended up working better than I thought.
public function Evaluate(expr : String) : String
return eval(expr, "unsafe");
command in the Visual Studio command prompt:
Microsoft.Jscript. You will
The value converter is actually very simple since only the
ConvertBack method has any significant code, and it has very little:
class EvaluationValueConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter,
public object ConvertBack(object value, Type targetType, object parameter,
if (value == null)
catch (Exception e)
Since there is no processing on the value from the ViewModel, the
Convert method just returns the value argument.
ConvertBack only has to pass the value
Eval() method through the
Evaluate method of an instance of the
is an exception because the string cannot be evaluated, an exception will be thrown, and then just pass null to the ViewModel. A nice thing is that the WPF
handles the problem with the null value being passed to the ViewModel; where the property is of type decimal or some other non-nullable type,
it changes the
TextBox border to red. What is nice is that the equation in the
TextBox can still be edited to correct errors.
Obviously this is not ideal because the value of the property in the ViewModel does not correspond to what is displayed, and the ViewModel does
not know that there is an issue with the user entry.
Calculation Engine Options
function will process these, but they are case sensitive, and must be preceded by “
Math.”. Another disadvantage is that it does not support the exponent
operator (“^”)--instead the
pow function must be used. Ideally, a better evaluator can be created, and there are a number
of good ones that can be found on the internet, but I wanted to avoid tramping on toes. The
Eval() function is very
powerful, and can do a lot more than anybody will probably want. A little bit of work could fix the problems with the
pow function and case sensitivity.
I found a number of other options on the internet:
All are good options, several would be better than mine since it would be more intuitive for the user.
The Example in Use
Here a user has entered an equation, but has not left the TextBox, therefore the value converter has not processed the equation to determine if it is invalid:
After leaving the TextBox, the value converter has determined that there is an error in the user input, and returned a null to the property, causing an error to be identified by the View:
Here the user is entering an equation with a transcendental function (this is before the focus leaves the TextBox):
After the focus leaves the TextBox, the following is displayed:
Fixing User Input Error Detection
The main problem with this approach is that there is no way for the ViewModel to know about equation errors if bound to a number property.
There is also the problem that the View really does not know about the error either, for disabling continuation. This could be fixed by making the number nullable,
but then the value displayed to the user would be reset, so that the user would not have the ability to fix the equation, also, the red error border would not
show. If knowing about input errors is important, then either the ViewModel will have to be enhanced, and a multi-value converter would need to be used, or
which will be the type of string.
The last solution is the one I think is best. If an indication is needed on the form for an error, then a value converter could be
used for some attribute (border, background, etc.) that would set the property to the invalid value if the property is non-numeric. The ViewModel would know
that the property is invalid because it is non-numeric. The only thing left would be to convert the property between a string value and the proper numeric
value for the Model. This is a little more work, but not bad for the functionality added.
What I would say is that this is a case that Microsoft missed an obvious feature in WPF; there is obviously an error, but no way to pass this information to the ViewModel.
Right now the value converter is not very smart, and if this converter is bound to a whole number type (e.g.,
Integer) format, and the
Eval() method returns
a floating or fixed point value, it will cause an error. This can easily be fixed by adding code that determines the type of the property being bound to, and does the
conversion before returning the value. This will also be a problem for overflow.
This value converter makes it very quick and easy to add the ability for the user to input equations in text boxes that are bound to numeric
properties. It has a problem in that if the user inputs an invalid equation, the ViewModel will not know that there is a problem, and so it is possible to
continue with an invalid equation in the text box. It this is acceptable, then this is a great option.
Eval() method to evaluate a string, and this can be used in other ways that may be more appropriate for the application.