Math in XAML
-
I would like to do some simple math in my WPF application with as much XAML code as possible and with as little C# code as possible. I have looked at various examples how to do this on diffrent web pages, but they are either to complex or don't show all details or lacks code or is just a bad example. Please run my XAML code, just copy and paste it:
<Setter Property="Control.HorizontalAlignment" Value="Left"></Setter> <Setter Property="Control.VerticalAlignment" Value="Top"></Setter> <Setter Property="Control.BorderBrush" Value="Black"></Setter> <Setter Property="Control.BorderThickness" Value="2"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontWeight" Value="Bold"></Setter> <Setter Property="Control.Height" Value="30"></Setter>
-
I would like to do some simple math in my WPF application with as much XAML code as possible and with as little C# code as possible. I have looked at various examples how to do this on diffrent web pages, but they are either to complex or don't show all details or lacks code or is just a bad example. Please run my XAML code, just copy and paste it:
<Setter Property="Control.HorizontalAlignment" Value="Left"></Setter> <Setter Property="Control.VerticalAlignment" Value="Top"></Setter> <Setter Property="Control.BorderBrush" Value="Black"></Setter> <Setter Property="Control.BorderThickness" Value="2"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontWeight" Value="Bold"></Setter> <Setter Property="Control.Height" Value="30"></Setter>
Short answer is "yes, it is possible". The long answer is a lot less pleasant: it can't be done for free. Pulling this trick requires work. In fact, it requires a lot of work. Here are the basic steps: 1. First, you need an expression library capable of evaluating expressions presented to it as strings. You can either build one (making a high-performance evaluation library on top of Linq expressions is surprisingly simple), or adopt one written by someone else (for example, this one: Expression Evaluator[^]). 2. Next, you will need to build a Converter class, which is a small adapter for using your expression evaluator in XAML. One class can implement both IMultiValueConverter.aspx[^] and IValueConverter[^], and expose a string property called "Source". 3. Import the assembly with your adapter into your XAML file by adding a clr-namespace referencing your assembly to the Windows element. xmlns:Converter="clr-namespace:MyNamespace.Converter;assembly=MyConverterAssembly" 4. Add a resource for each expression that you would like evaluated from your XAML:
<Converter:ExpressionValueConverter
x:Key="CalcTotalWeight"
Source="(arg1 * 126) + (arg2 * 220)"
/>5. Use binding or multi-binding to attach your expression to labels and text boxes in your XAML:
<MultiBinding Converter="{StaticResource CalcTotalWeigh}" FallbackValue="0">
<Binding Path="txtA"/>
<Binding Path="txtB"/>
</MultiBinding>I went through this exercise once, and I can tell you that it is not easy. And I started with a well-tested expression library from step 1! But once you put it all together, it looks like a small miracle.
-
I would like to do some simple math in my WPF application with as much XAML code as possible and with as little C# code as possible. I have looked at various examples how to do this on diffrent web pages, but they are either to complex or don't show all details or lacks code or is just a bad example. Please run my XAML code, just copy and paste it:
<Setter Property="Control.HorizontalAlignment" Value="Left"></Setter> <Setter Property="Control.VerticalAlignment" Value="Top"></Setter> <Setter Property="Control.BorderBrush" Value="Black"></Setter> <Setter Property="Control.BorderThickness" Value="2"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontSize" Value="15"></Setter> <Setter Property="Control.FontWeight" Value="Bold"></Setter> <Setter Property="Control.Height" Value="30"></Setter>
You could accomplish this entirely in your XAML by using inline code (it's not pretty, and it's not good practice, but it is possible). Basically, you would implement an <x:Code> section where you would put the code in place to handle the calculations, etc. The important thing to remember is that you should encode your code so that you have something that looks like this:<x:Code> <![CDATA[ // Do your work here ]]> </x:Code>
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Short answer is "yes, it is possible". The long answer is a lot less pleasant: it can't be done for free. Pulling this trick requires work. In fact, it requires a lot of work. Here are the basic steps: 1. First, you need an expression library capable of evaluating expressions presented to it as strings. You can either build one (making a high-performance evaluation library on top of Linq expressions is surprisingly simple), or adopt one written by someone else (for example, this one: Expression Evaluator[^]). 2. Next, you will need to build a Converter class, which is a small adapter for using your expression evaluator in XAML. One class can implement both IMultiValueConverter.aspx[^] and IValueConverter[^], and expose a string property called "Source". 3. Import the assembly with your adapter into your XAML file by adding a clr-namespace referencing your assembly to the Windows element. xmlns:Converter="clr-namespace:MyNamespace.Converter;assembly=MyConverterAssembly" 4. Add a resource for each expression that you would like evaluated from your XAML:
<Converter:ExpressionValueConverter
x:Key="CalcTotalWeight"
Source="(arg1 * 126) + (arg2 * 220)"
/>5. Use binding or multi-binding to attach your expression to labels and text boxes in your XAML:
<MultiBinding Converter="{StaticResource CalcTotalWeigh}" FallbackValue="0">
<Binding Path="txtA"/>
<Binding Path="txtB"/>
</MultiBinding>I went through this exercise once, and I can tell you that it is not easy. And I started with a well-tested expression library from step 1! But once you put it all together, it looks like a small miracle.
-
You could accomplish this entirely in your XAML by using inline code (it's not pretty, and it's not good practice, but it is possible). Basically, you would implement an <x:Code> section where you would put the code in place to handle the calculations, etc. The important thing to remember is that you should encode your code so that you have something that looks like this:<x:Code> <![CDATA[ // Do your work here ]]> </x:Code>
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Theres already one built for you. http://wpfconverters.codeplex.com/wikipage?title=User%20Documentation#ExpressionConverter[^]