WPF PriceBox Control that displays an up/down arrow next to a price

Price Up down Tickers

Many financial applications you see show prices displayed with an arrow next to them, that indicates if the price has moved up or down relevant to the previous price.

This is what PriceBox does for you. You just assign it a price and if it is higher then the last price it will display an up arrow and if it’s less then the previous it will display a down arrow.

Here is an example of what PriceBox looks like:

[button link=”http://www.jarloo.com/downloads/PriceBox.zip” type=”icon”]Download the Source Code[/button]

How PriceBox Works

When you assign a price PriceBox looks at it and determines if it’s higher or lower then the last one. (it keeps a field with the last price so it can do this check)

PriceBox has an Polygon in the shape of an arrow that regularly points up. To make the arrow point down or sideways if the price is unchanged, PriceBox modifies the rotation angle of the arrow.

So if the price is lower then the last price the arrow will have a rotation angle of 180 so it points down. If the price is unchanged the rotation angle will be 90, and if the price is greater then the last price the angle will be 0.

PriceBox Class Code

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace JarlooPriceControls
    public class PriceBox : Control
        public static readonly DependencyProperty PriceProperty = DependencyProperty.Register("Price", typeof (decimal), typeof (PriceBox), new PropertyMetadata(0m));
        public static readonly DependencyProperty ArrowUpColorProperty = DependencyProperty.Register("ArrowUpColor", typeof (Brush), typeof (PriceBox), new PropertyMetadata(new SolidColorBrush(Colors.Green)));
        public static readonly DependencyProperty ArrowDownColorProperty = DependencyProperty.Register("ArrowDownColor", typeof (Brush), typeof (PriceBox), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
        public static readonly DependencyProperty ArrowColorProperty = DependencyProperty.Register("ArrowColor", typeof (Brush), typeof (PriceBox), new PropertyMetadata(new SolidColorBrush(Colors.Black)));
        public static readonly DependencyProperty ArrowAngleProperty = DependencyProperty.Register("ArrowAngle", typeof (int), typeof (PriceBox), new PropertyMetadata(0));

        public int ArrowAngle
            get { return (int) GetValue(ArrowAngleProperty); }
            set { SetValue(ArrowAngleProperty, value); }

        public Brush ArrowColor
            get { return (Brush) GetValue(ArrowColorProperty); }
            set { SetValue(ArrowColorProperty, value); }

        public Brush ArrowDownColor
            get { return (Brush) GetValue(ArrowDownColorProperty); }
            set { SetValue(ArrowDownColorProperty, value); }

        public Brush ArrowUpColor
            get { return (Brush) GetValue(ArrowUpColorProperty); }
            set { SetValue(ArrowUpColorProperty, value); }

        public decimal Price
            get { return (decimal) GetValue(PriceProperty); }
                        SetValue(ArrowColorProperty, GetValue(ArrowDownColorProperty));
                        SetValue(ArrowAngleProperty, 180);
                    else if(lastPrice<value)
                        SetValue(ArrowColorProperty, GetValue(ArrowUpColorProperty));
                        SetValue(ArrowAngleProperty, 0);
                        SetValue(ArrowColorProperty, new SolidColorBrush(Colors.Black));
                        SetValue(ArrowAngleProperty, 90);

                lastPrice = (decimal) GetValue(PriceProperty);
                SetValue(PriceProperty, value);

        private decimal? lastPrice;

        static PriceBox()
            DefaultStyleKeyProperty.OverrideMetadata(typeof (PriceBox), new FrameworkPropertyMetadata(typeof (PriceBox)));

        public PriceBox()
            DataContext = this;

Theme Code (Generic.xaml)


    <Style TargetType="{x:Type local:PriceBox}">
        <Setter Property="Template">
                <ControlTemplate TargetType="{x:Type local:PriceBox}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">

                        <StackPanel Orientation="Horizontal"  HorizontalAlignment="Right" >
                            <TextBlock Text="{Binding Path=Price, StringFormat=\{0:###\,##0.00\}}" Foreground="{TemplateBinding Foreground}" TextAlignment="Right" HorizontalAlignment="Stretch" />

                            <Polygon Margin="1,0,0,12" Points="0,10 10,0 20,10" RenderTransformOrigin="0.5,0.5" Fill="{Binding ArrowColor}" Stroke="{Binding ArrowColor}" Stretch="Fill" Width="8.668" Height="5.334" VerticalAlignment="Bottom" HorizontalAlignment="Left">
                                    <RotateTransform Angle="{Binding ArrowAngle}" />


Categories:   Code, Finance

Tags:  , ,


  • Posted: November 6, 2014 12:05

    Bhushan Poojary

    Hello, Nice stuff, you did one mistake, never put anything in setter of dependency property. Because it may never be called. Instead of it call it in Meta Value changed event. I used it and later it worked fine with Datagrid. Thanks.