OK, so I am pretty sure I’m on the right track with this small application, but let me know. The user enters in 3 of the 4 numbers into the 4 editable textboxes, and the missing number is calculated automatically. Picture of app here:
http://www.peauproductions.com/images/lens_app.PNG
I have looked at data binding, and I think I need to have the values able to globally change. I want the values to dynamically update/compute and not have to have a calculate button.
Once I get it working I need to implement a validation check to make sure a boolean is only entered (no text), and have a tooltip pop up saying to enter a number.
Getting the following ERROR right now:
“‘Set property ‘System.Windows.Controls.TextBox.Text’ threw an exception.’ Line number ’56’ and line position ’51’.”
MainWindow.xaml Code:
<Window x:Class="ConverterApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConverterApp" Height="360" Width="280"
xmlns:c="clr-namespace:ConvertorApp;assembly=">
<Grid>
<!--Outer Box + Title-->
<TextBox Height="309" Width="248"
Text=" Lens Calculator"
IsReadOnly="True"
Margin="5,5,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="2.0"
FontSize="16" FontFamily="Verdana" FontWeight="Bold">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Title Text-->
<TextBox Height="50" Width="230"
Text="Enter Image Width, Length and Either Distance or Lens Values Below"
IsReadOnly="True"
Margin="14,29,0,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontSize="12" FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<TextBox Height="20" Width="230"
Text="Must Be Same Units (in,ft,cm,mm)"
IsReadOnly="True"
Margin="14,59,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontSize="10" FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<!--Distance-->
<TextBox Height="20" Width="105"
Text="Distance/Height:"
IsReadOnly="True"
Margin="15,80,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="DistanceBox" Height="20" Width="50"
Text="{x:Static c:Variables.DistanceBox}"
Margin="125,80,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Image Width-->
<TextBox Height="20" Width="90"
Text="Image Width:"
IsReadOnly="True"
Margin="15,105,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="WidthBox" Height="20" Width="50"
Text="{x:Static c:Variables.WidthBox}"
Margin="125,105,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Image Length-->
<TextBox Width="95"
Text="Image Length:"
IsReadOnly="True"
Margin="15,130,0,161" HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="LengthBox" Height="20" Width="50"
Text="{x:Static c:Variables.LengthBox}"
Margin="125,130,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Lens Needed-->
<TextBox Height="20" Width="90"
Text="Lens (mm):"
IsReadOnly="True"
Margin="15,155,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="LensNeeded" Height="20" Width="50"
Text="{x:Static c:Variables.LensNeeded}"
Margin="125,155,0,0"
MaxLength="4"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Info-->
<TextBox Height="70" Width="230"
Text="The lens focal length value represents the estimated mm value for a 1/4 inch sensor (Playstation Eye). A lower mm will give a wider Field of View (FOV), and a higher value less FOV. "
IsReadOnly="True"
TextWrapping="Wrap"
Margin="15,180,0,0"
FontSize="11"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<TextBox Height="55" Width="230"
Text="It is not recommend you use a lens of less than 2.5mm focal length with image tracking software due to distortion."
IsReadOnly="True"
FontSize="11"
TextWrapping="Wrap"
Margin="15,253,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
</Grid>
MainWindow.xaml.cs Code:
using System;
using System.Windows;
namespace ConvertorApp
{
public class Variables
{
public const double DistanceBox = 0;
public const double WidthBox = 0;
public const double LengthBox = 0;
public const double LensNeeded = 0;
public const double WidthBased = 0;
public const double LengthBased = 0;
public void Calc()
{
double WidthBased = 2.952*(DistanceBox/WidthBox);
double LengthBased = 3.984*(DistanceBox/LengthBox);
if (WidthBased < LengthBased)
{
double LensNeeded = WidthBased;
}else{
double LensNeeded = LengthBased;
}
}
}
}
If you can think of an easier, or more correct way to go about what I’m trying to do, please let me know (I just started learning this WPF/C# stuff). Thanks
UPDATE:
Here is the back code showing suggested changes from below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace ConverterApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Variables();
}
}
public class Variables : INotifyPropertyChanged
{
// Declare the PropertyChanged event.
public event PropertyChangedEventHandler PropertyChanged;
private double m_distanceBox;
public double DistanceBox
{
get { return m_distanceBox; }
set
{
m_distanceBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("DistanceBox");
}
}
private double m_widthBox;
public double WidthBox
{
get { return m_widthBox; }
set
{
m_widthBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("WidthBox");
}
}
private double m_lengthBox;
public double LengthBox
{
get { return m_lengthBox; }
set
{
m_lengthBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("LengthBox");
}
}
private double m_lensBox;
public double LensNeeded
{
get { return m_lensBox; }
set
{
m_lensBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("LensNeeded");
}
}
public void Calc()
{
double WidthBased = 2.95 * (DistanceBox / WidthBox);
double LengthBased = 3.98 * (DistanceBox / LengthBox);
if (WidthBased < LengthBased)
{
LensNeeded = Math.Round(WidthBased,2);
}else{
LensNeeded = Math.Round(LengthBased,2);
}
}
// NotifyPropertyChanged will raise the PropertyChanged event,
// passing the source property that is being updated.
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
}
**ERROR I’m now getting is the StackOverflowException on the get {} inside the double functions. Any ideas?
The exception is thrown because the line
is effectively something like
This wouldn’t compile in C#. In XAML, it throws exception. What you should do instead is create properties from your fields:
And set
VariablesasDataContextof your window, by addingto the constructor of your window (or handler of the
Loadedevent).You then use bindings in your XAML (which uses a converter to make
strings out ofdoubles):To call
Calc()whenever a value changes, you can change the property toTo make sure changes in
Variablesare reflected in the text boxes, you should implement theINotifyPropertyChangedinterface.EDIT: C# code of
MainWindow: