Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / WPF

WPF Margin Calculator Control

Rate me:
Please Sign up or sign in to vote.
2.67/5 (3 votes)
10 Sep 2010CPOL2 min read 30.1K   339   3   7
.NET 4.0 WPF control that allows you to enter a cost and sale price and compute a margin.

Introduction

This is a WPF user control that I recently created for a project I'm working on.

It's pretty basic, you enter a cost and optionally a sale price and it will tell you what price to sell the item for and what margin you will make on it, as well as profit.

The UI for the control is made up of some basic WPF controls and includes some simple gradient backgrounds.

There is also a cool glass button, that is located in the UserControl.Resources section.
You can take the control template for the Glass Button and customize it to fit your needs.

I have included a demo application with the code download, as well as a screenshot below.

MarginCalculator.png

Using the Code

To use this control, just right-click the toolbox in Visual Studio and add a reference to the
CodeLogix.Controls.MarginCalculator namespace.

This will add the control to the toolbox and allow you to drag and drop it on your WPF design surface.

NOTE: I have also included a simple numeric only textbox for WPF in the download.

This will allow you to input only numbers and the decimal separator into the Cost and Sale Price fields.

The code for it is pretty simple, we just sub-class the System.Windows.Controls.TextBox class and override the OnPreviewTextInput method. Then we need to create a helper method to verify valid input.

Numeric Only TextBox Code

C#
   protected override void OnPreviewTextInput
	(System.Windows.Input.TextCompositionEventArgs e)
    {
        e.Handled = !AreAllValidNumericChars(e.Text);
        base.OnPreviewTextInput(e); 
    }
    
    static bool AreAllValidNumericChars(string str)
    {
        bool ret = true;
        if (str == System.Globalization.NumberFormatInfo.CurrentInfo.
		CurrencyDecimalSeparator |                
            str == System.Globalization.NumberFormatInfo.
		CurrentInfo.NumberDecimalSeparator)
            
            return ret;
            
        int l = str.Length;
        for (int i = 0; i < l; i++)
        {
            char ch = str[i];
            ret &= Char.IsDigit(ch);
        }
        
        return ret;
    }
}

Margin Calculator Code

C#
public partial class MarginCalculator : UserControl
{       
    public MarginCalculator()
    {
        InitializeComponent();
    }
    
    // This is used to store the values for the different margin textBlock controls.
    internal struct MarginValues
    {           
        public double TwentyFivePercent { get; set; }
        public double ThirtyPercent { get; set; }
        public double ThirtyFivePercent { get; set; }
        public double FortyPercent { get; set; }
        public double FortyFivePercent { get; set; }
        public double FiftyPercent { get; set; }
        public double FiftyFivePercent { get; set; }
        public double SixtyPercent { get; set; }
        public double SixtyFivePercent { get; set; }
    }
    
    // Here we calculate the profit margin, by subtracting the sale price, 
    // minus the cost, divided by the sale price. 
    
    private static double CalculateProfitMargin(double cost, double salePrice)
    {
        return (salePrice - cost) / salePrice;
    }
    
    private static MarginValues CalculateMargin(double costOfPart)
    {
        MarginValues values = new MarginValues 
        { 
            TwentyFivePercent = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.73))), 
            ThirtyPercent     = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.68))), 
            ThirtyFivePercent = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.63))), 
            FortyPercent      = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.58))), 
            FortyFivePercent  = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.53))), 
            FiftyPercent      = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.49))), 
            FiftyFivePercent  = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.44))), 
            SixtyPercent      = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.39))), 
            SixtyFivePercent  = Math.Round(((1 - Convert.ToDouble(costOfPart)) / (-0.34))) 
        };
        return values;
    }
    
    // Here we check for valid input and compute the results. 
    private void RunCalculations()
    {
        MarginValues results = new MarginValues();
        if (!String.IsNullOrEmpty(textBoxCostOfPart.Text))
        {
            double cost;
            if (double.TryParse(textBoxCostOfPart.Text, out cost))
            {
                results = CalculateMargin(cost);
                if (!String.IsNullOrEmpty(textBoxSalePrice.Text))
                {
                    double salePrice;
                    if (double.TryParse(textBoxSalePrice.Text, out salePrice))
                    {
                        double profitMargin = CalculateProfitMargin(cost, salePrice);
                        margin.Text = profitMargin.ToString("p");
                        double profit = salePrice - cost;
                        this.profit.Text = profit.ToString("c");
                    }
                }
            }
        }
        // set the percent textblocks
        twentyFivePercent.Text = results.TwentyFivePercent.ToString("c");
        thirtyPercent.Text     = results.ThirtyPercent.ToString("c");
        thirtyFivePercent.Text = results.ThirtyFivePercent.ToString("c");
        fortyPercent.Text      = results.FortyPercent.ToString("c");
        fortyFivePercent.Text  = results.FortyFivePercent.ToString("c");
        fiftyPercent.Text      = results.FiftyPercent.ToString("c");
        fiftyFivePercent.Text  = results.FiftyFivePercent.ToString("c");
        sixtyPercent.Text      = results.SixtyPercent.ToString("c");
        sixtyFivePercent.Text  = results.SixtyFivePercent.ToString("c");
    }
    
     // The rest of the code simply invokes the calculation code,
    // whenever a user clicks the GO button, or types valid input into the
    // Cost or Sale Price textBox.
    private void buttonCalculate_Click(object sender, RoutedEventArgs e)
    {
       RunCalculations();
    }
     
    private void textBoxCostOfPart_KeyDown(object sender, KeyEventArgs e)
    {
        RunCalculations();
    }
    
    private void textBoxSalePrice_KeyDown(object sender, KeyEventArgs e)
    {
        RunCalculations();
    }
    
    private void textBoxCostOfPart_GotFocus(object sender, RoutedEventArgs e)
    {
        textBoxCostOfPart.SelectAll();
    }
    
    private void textBoxSalePrice_GotFocus(object sender, RoutedEventArgs e)
    {
        textBoxSalePrice.SelectAll();
    }
    
    private void textBoxSalePrice_GotMouseCapture(object sender, MouseEventArgs e)
    {
        textBoxSalePrice.SelectAll();
    }
    
    private void textBoxCostOfPart_GotMouseCapture(object sender, MouseEventArgs e)
    {
        textBoxCostOfPart.SelectAll();
    }
}

If anyone finds this control useful and/or has any way to improve it, please leave a comment and let me know.

Points of Interest (ToolBox Icon)

One thing I did was to add a custom icon for my control to the ToolBox in Visual Studio. If anyone is unsure how to do this, let me explain.

  1. First you need to add an image at the same level in your project, as your user control.
  2. Then make sure you rename the image to be UserControlName.Icon.YourImageExtension.
  3. Next, make sure you set the image to be an embedded resource in the properties window.

NOTE: Your custom icon will not show up in the automatically added toolbox items for your user control.

You will need to Right-Click and Add Item, then browse to your User Control's assembly and add it to the toolbox.

Then everything will work as expected.

History

  • 9/2/2010: Uploaded first version of Control

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
United States United States
I'm a .NET developer currently into ASP.NET MVC, WPF 4 and Visual Studo 2010.

I have no problem programming in both C# and VB, and have even written a game for XNA using C#.

Comments and Discussions

 
GeneralFormat it properly Please Pin
Hiren solanki10-Sep-10 19:47
Hiren solanki10-Sep-10 19:47 
GeneralMy vote of 1 Pin
MadZookeeper7-Sep-10 4:04
MadZookeeper7-Sep-10 4:04 
GeneralFixed values Pin
DaveAuld3-Sep-10 5:25
professionalDaveAuld3-Sep-10 5:25 
GeneralRe: Fixed values Pin
codelogix10-Sep-10 8:21
codelogix10-Sep-10 8:21 
GeneralRe: Fixed values Pin
Glenn Dawson10-Sep-10 11:28
Glenn Dawson10-Sep-10 11:28 
GeneralNot really an article... Pin
Dave Kreskowiak2-Sep-10 10:07
mveDave Kreskowiak2-Sep-10 10:07 
GeneralRe: Not really an article... Pin
codelogix2-Sep-10 10:38
codelogix2-Sep-10 10:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.