Flaming Idiots
Active Member
First is the calculator source. While it is really big, it shouldn't be too hard to use.
Here is an example of how to use it:
Here is the code for the calculator. I suggest you put it in its own file.
Now for the count down timer, it is simple to use. Add the code to your project (should be in its own file) build it, and there should be a CountDownTimer on your toolbox.
Here is an example for using it (I set the countdowntimer's time to 00:00:05(5 seconds)):
And here is the code for the timer itself:
Feel free to use both, just give credit. Also if anyone can find problems with the calculator, please tell me.
Here is an example of how to use it:
Code:
Dim Exp As New MathExpressionParser()
Dim Result = Exp.ParseExpression("4+5^2-sin(8)").Invoke
Code:
Public NotInheritable Class MathExpressionParser
Sub New()
With VariableTable
.Add("pi", Math.PI)
.Add("e", Math.E)
.Add("x", Function() Me.X)
End With
With FunctionTable
.Add("sum", AddressOf Functions.Sum)
.Add("average", AddressOf Functions.Average)
.Add("min", AddressOf Functions.Min)
.Add("max", AddressOf Functions.Max)
.Add("floor", AddressOf Math.Floor)
.Add("ceil", AddressOf Math.Ceiling)
.Add("sin", AddressOf Math.Sin)
.Add("cos", AddressOf Math.Cos)
.Add("tan", AddressOf Math.Tan)
.Add("sinh", AddressOf Math.Sinh)
.Add("cosh", AddressOf Math.Cosh)
.Add("tanh", AddressOf Math.Tanh)
.Add("abs", AddressOf Math.Abs)
.Add("round", AddressOf Math.Round)
.Add("~", AddressOf Math.Round)
.Add("sqrt", AddressOf Math.Sqrt)
.Add("if", Function(Val As Decimal, [True] As Decimal, [False] As Decimal) If(Val <> 0, [True], [False]))
.Add("?", Function(Val As Decimal, [True] As Decimal, [False] As Decimal) If(Val <> 0, [True], [False]))
.Add("add", Function(Left As Decimal, Right As Decimal) Left + Right)
.Add("sub", Function(Left As Decimal, Right As Decimal) Left - Right)
.Add("mul", Function(Left As Decimal, Right As Decimal) Left * Right)
.Add("div", Function(Left As Decimal, Right As Decimal) Left / Right)
.Add("mod", Function(Left As Decimal, Right As Decimal) Left Mod Right)
.Add("pow", Function(Left As Decimal, Right As Decimal) Left ^ Right)
.Add("root", Function(Left As Decimal, Right As Decimal) Left ^ If(Right = 0, 0, (1 / Right)))
End With
With OperatorTable
.Add("+", AddressOf DecimalExpression.Add, OperatorTable.OperatorLevel.Additive)
.Add("-", AddressOf DecimalExpression.Subtract, OperatorTable.OperatorLevel.Additive)
.Add("*", AddressOf DecimalExpression.Multiply, OperatorTable.OperatorLevel.Multiplicative)
.Add("/", AddressOf DecimalExpression.Divide, OperatorTable.OperatorLevel.Multiplicative)
.Add("%", AddressOf DecimalExpression.Modulo, OperatorTable.OperatorLevel.Multiplicative)
.Add("^", AddressOf DecimalExpression.Power, OperatorTable.OperatorLevel.Exponential)
.Add("<", AddressOf DecimalExpression.LessThan, OperatorTable.OperatorLevel.Comparitive)
.Add(">", AddressOf DecimalExpression.GreaterThan, OperatorTable.OperatorLevel.Comparitive)
.Add("=", AddressOf DecimalExpression.Equals, OperatorTable.OperatorLevel.Comparitive)
.Add("!", AddressOf DecimalExpression.NotEqual, OperatorTable.OperatorLevel.Comparitive)
.Add("|", AddressOf DecimalExpression.Or, OperatorTable.OperatorLevel.Comparitive)
.Add("&", AddressOf DecimalExpression.And, OperatorTable.OperatorLevel.Comparitive)
End With
End Sub
Private Class Functions
Public Shared Function Sum(ByVal Items As Decimal()) As Decimal
Sum = 0
For Each I In Items
Sum += I
Next
End Function
Public Shared Function Average(ByVal Items As Decimal()) As Decimal
Return Sum(Items) / Items.Length
End Function
Public Shared Function Min(ByVal Items As Decimal()) As Decimal
Min = Items(0)
For Each I In Items
Min = Math.Min(Min, I)
Next
End Function
Public Shared Function Max(ByVal Items As Decimal()) As Decimal
Max = Items(0)
For Each I In Items
Max = Math.Max(Max, I)
Next
End Function
End Class
Public Function ParseExpression(ByVal Expression As String) As DecimalExpression
Return Combine(SplitExpression(Expression))
End Function
Private Function SplitExpression(ByVal Expression As String) As String()
Dim L = New List(Of String)
Dim OPs = Aggregate I In OperatorTable Select I.Symbol Into ToArray() 'New Char() {"+", "-", "*", "/", "%", "^", "<", ">", "=", "!", "&", "|"}
Dim WasOP As Boolean = True
Dim Current = ""
Dim BracketLevel = 0
For Each C In Expression.Replace(" ", "")
If C = "("c Then BracketLevel += 1
If C = ")"c Then BracketLevel -= 1
If WasOP Then
WasOP = False
If Current.Length > 0 Then L.Add(Current.Trim)
Current = C
Else
If OPs.Contains(C) AndAlso BracketLevel = 0 Then
If Current.Length > 0 Then L.Add(Current.Trim)
Current = C
WasOP = True
Else
Current &= C
End If
End If
Next
If Current.Length > 0 Then L.Add(Current)
Return L.ToArray
End Function
Private Function SplitParams(ByVal Expression As String) As String()
Dim L = New List(Of String)
Dim OPs = New Char() {","}
Dim WasOP As Boolean = False
Dim Current = ""
Dim BracketLevel = 0
For Each C In Expression.Replace(" ", "")
If C = "("c Then BracketLevel += 1
If C = ")"c Then BracketLevel -= 1
If WasOP Then
WasOP = False
If Current.Length > 0 Then L.Add(Current.Trim)
Current = C
Else
If OPs.Contains(C) AndAlso BracketLevel = 0 Then
If Current.Length > 0 Then L.Add(Current.Trim)
Current = C
WasOP = True
Else
Current &= C
End If
End If
Next
If Current.Length > 0 Then L.Add(Current)
Return L.Where(Function(c As String) c <> ",").ToArray
End Function
Private Function Combine(ByVal Split As String()) As DecimalExpression
Dim Vals As New List(Of DecimalExpression)
Dim Ops As New List(Of OperatorTable.OperatorReference)
For Each I In Split
If I.Length = 1 AndAlso OperatorTable.ContainsOperator(I) Then
Ops.Add(OperatorTable(I))
Else
If I.StartsWith("(") Then
Vals.Add(Combine(SplitExpression(I.Substring(1, I.Length - 2))))
ElseIf I.EndsWith(")") Then
Dim name = I.Split("(").First.ToLower
Dim Params = Aggregate Param In SplitParams(I.Substring(name.Length + 1, I.Length - name.Length - 2)) Select Me.ParseExpression(Param) Into ToArray()
Vals.Add(GetFunction(name, Params))
Else
Vals.Add(ParseValue(I))
End If
End If
Next
S:
For Each G In [Enum].GetValues(GetType(OperatorTable.OperatorLevel)).Cast(Of OperatorTable.OperatorLevel)()
For n = 0 To Ops.Count - 1
Dim OP = Ops(n)
If G = OP.Level Then
Dim Left = Vals(n), Right = Vals(n + 1)
Dim E = OP.Operator(Left, Right)
Ops.Remove(OP)
Vals.RemoveRange(n, 2)
Vals.Insert(n, E)
GoTo S
End If
Next
Next
Return Vals.First
End Function
Private Function ParseValue(ByVal E As String) As DecimalExpression
If System.Text.RegularExpressions.Regex.IsMatch(E, "\-?[\d\.]+") Then Return Decimal.Parse(E) Else Return GetVariable(E)
End Function
Private _variableTable As New VariableTable
Public ReadOnly Property VariableTable() As VariableTable
Get
Return _variableTable
End Get
End Property
Private _functionTable As New FunctionTable
Public ReadOnly Property FunctionTable() As FunctionTable
Get
Return _functionTable
End Get
End Property
Private _operatorTable As New OperatorTable
Public ReadOnly Property OperatorTable() As OperatorTable
Get
Return _operatorTable
End Get
End Property
Private Function GetVariable(ByVal name As String) As DecimalExpression
Dim Result As DecimalExpression = 0
Dim Neg = name.StartsWith("-")
If Neg Then name = name.Substring(1)
Dim V = VariableTable.IsConstant(name)
If V.HasValue AndAlso V.Value Then Return If(Neg, -VariableTable(name), VariableTable(name))
Result = DecimalExpression.Func(Function() If(VariableTable.ContainsVariable(name), VariableTable(name), 0D))
Return If(Neg, DecimalExpression.Multiply(-1, Result), Result)
End Function
Private Function GetFunction(ByVal name As String, ByVal ParamArray args() As DecimalExpression) As DecimalExpression
Dim Result As DecimalExpression = 0
Dim Neg = name.StartsWith("-")
If Neg Then name = name.Substring(1)
Result = DecimalExpression.Func(Function() If(FunctionTable.ContainsFunction(name.ToLower), DynInvoke(name, args), 0))
Return If(Neg, DecimalExpression.Multiply(-1, Result), Result)
End Function
Private Function DynInvoke(ByVal Name As String, ByVal Args() As DecimalExpression) As Decimal
Dim Method = FunctionTable(Name.ToLower)
If Method.Method.GetParameters().First().ParameterType.IsArray Then
Return Method.DynamicInvoke(Aggregate I In Args Select CDec(I.Invoke) Into ToArray())
Else
Return Method.DynamicInvoke(Aggregate I In Args Select CObj(I.Invoke) Into ToArray())
End If
End Function
Private _x As Decimal
Public Property X() As Decimal
Get
Return _x
End Get
Set(ByVal value As Decimal)
_x = value
End Set
End Property
End Class
Public NotInheritable Class FunctionTable
Private Items As New Dictionary(Of String, [Delegate])
Public Sub Add(ByVal Name As String, ByVal [Function] As Func(Of Decimal, Decimal))
Items.Add(Name.ToLower, [Function])
End Sub
Public Sub Add(ByVal Name As String, ByVal [Function] As Func(Of Decimal, Decimal, Decimal))
Items.Add(Name.ToLower, [Function])
End Sub
Public Sub Add(ByVal Name As String, ByVal [Function] As Func(Of Decimal, Decimal, Decimal, Decimal))
Items.Add(Name.ToLower, [Function])
End Sub
Public Sub Add(ByVal Name As String, ByVal [Function] As Func(Of Decimal, Decimal, Decimal, Decimal, Decimal))
Items.Add(Name.ToLower, [Function])
End Sub
Public Sub Add(ByVal Name As String, ByVal [Function] As [Delegate])
Items.Add(Name.ToLower, [Function])
End Sub
Public Sub Add(ByVal Name As String, ByVal [Function] As Func(Of Decimal(), Decimal))
Items.Add(Name.ToLower, [Function])
End Sub
Public Function ContainsFunction(ByVal Name As String) As Boolean
Return Items.ContainsKey(Name.ToLower)
End Function
Default Public ReadOnly Property [Function](ByVal Name As String) As [Delegate]
Get
Return If(Items.ContainsKey(Name.ToLower), Items(Name.ToLower), Nothing)
End Get
End Property
Public Sub RemoveFunction(ByVal Name As String)
If ContainsFunction(Name) Then Items.Remove(Name.ToLower)
End Sub
End Class
Public NotInheritable Class VariableTable
Private Items As New Dictionary(Of String, Func(Of Decimal))
Private ConstTable As New Dictionary(Of String, Boolean)
Public Sub Add(ByVal Name As String, ByVal Provider As Func(Of Decimal))
Items.Add(Name.ToLower, Provider)
ConstTable.Add(Name.ToLower, False)
End Sub
Public Sub Add(ByVal Name As String, ByVal Value As Decimal)
Items.Add(Name.ToLower, Function() Value)
ConstTable.Add(Name.ToLower, True)
End Sub
Public Function ContainsVariable(ByVal Name As String) As Boolean
Return Items.ContainsKey(Name.ToLower)
End Function
Public Function IsConstant(ByVal Name As String) As Boolean?
Return If(ConstTable.ContainsKey(Name.ToLower), ConstTable(Name.ToLower), Nothing)
End Function
Default Public ReadOnly Property Value(ByVal Name As String) As Decimal
Get
Return If(Items.ContainsKey(Name.ToLower), Items(Name.ToLower).Invoke, 0D)
End Get
End Property
Public Sub RemoveVariable(ByVal Name As String)
If ContainsVariable(Name) Then Items.Remove(Name.ToLower)
End Sub
End Class
Public NotInheritable Class OperatorTable
Implements IEnumerable(Of OperatorReference)
Private Items As New List(Of OperatorReference)
Public Sub Add(ByVal Symbol As Char, ByVal [Operator] As [Operator], ByVal Level As OperatorLevel)
Items.Add(New OperatorReference(Symbol, [Operator], Level))
End Sub
Public Function ContainsOperator(ByVal Symbol As Char) As Boolean
Return Items.SingleOrDefault(Function(I As OperatorReference) I.Symbol = Symbol) IsNot Nothing
End Function
Default Public ReadOnly Property Value(ByVal Symbol As Char) As OperatorReference
Get
Return Items.SingleOrDefault(Function(I As OperatorReference) I.Symbol = Symbol)
End Get
End Property
Public Sub RemoveVariable(ByVal Symbol As Char)
Dim Op = Items.SingleOrDefault(Function(I As OperatorReference) I.Symbol = Symbol)
If Op IsNot Nothing Then Items.Remove(Op)
End Sub
Public Class OperatorReference
Sub New(ByVal Symbol As Char, ByVal [Operator] As [Operator], ByVal Level As OperatorLevel)
Me._symbol = Symbol : Me._Operator = [Operator] : Me._level = Level
End Sub
Private _symbol As Char
Public ReadOnly Property Symbol() As Char
Get
Return _symbol
End Get
End Property
Private _Operator As [Operator]
Public ReadOnly Property [Operator]() As [Operator]
Get
Return _Operator
End Get
End Property
Private _level As OperatorLevel
Public ReadOnly Property Level() As OperatorLevel
Get
Return _level
End Get
End Property
End Class
Public Enum OperatorLevel
Exponential
Multiplicative
Additive
Comparitive
End Enum
Private Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of OperatorReference) Implements System.Collections.Generic.IEnumerable(Of OperatorReference).GetEnumerator
Return Me.Items.GetEnumerator
End Function
Private Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return Me.Items.GetEnumerator
End Function
End Class
Public Delegate Function [Operator](ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
Public NotInheritable Class DecimalExpression
Private Sub New(ByVal Expression As Func(Of Decimal))
Me.expression = Expression
Me.IsStatic = False
End Sub
Private Sub New(ByVal Value As Decimal)
Me.expression = Function() Value
Me.IsStatic = True
End Sub
Private expression As Func(Of Decimal)
Public Function Invoke() As Decimal
Try
Return expression.Invoke
Catch ex As Exception
Throw ex
End Try
End Function
Public Function Invoke(ByVal DefualtValue As Decimal) As Decimal
Try
Return expression.Invoke
Catch ex As Exception
Return DefualtValue
End Try
End Function
Private IsStatic As Boolean = False
Public Shared Widening Operator CType(ByVal Value As Decimal) As DecimalExpression
Return New DecimalExpression(Value)
End Operator
Public Shared Narrowing Operator CType(ByVal Value As Func(Of Decimal)) As DecimalExpression
Return New DecimalExpression(Value)
End Operator
Public Shared Function Constant(ByVal Value As Decimal) As DecimalExpression
Return New DecimalExpression(Value)
End Function
Public Shared Function Add(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return Left.Invoke + Right.Invoke
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return Right.Invoke
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return Left.Invoke
Return New DecimalExpression(Function() (Left.Invoke + Right.Invoke))
End Function
Public Shared Function Subtract(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke - Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return -Right.Invoke
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return Left.Invoke
Return New DecimalExpression(Function() (Left.Invoke - Right.Invoke))
End Function
Public Shared Function Multiply(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke * Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return 0
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return 0
Return New DecimalExpression(Function() (Left.Invoke * Right.Invoke))
End Function
Public Shared Function Divide(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke / Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return 0
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return 0
Return New DecimalExpression(Function() (Left.Invoke / Right.Invoke))
End Function
Public Shared Function Power(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke ^ Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return 0
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return 1
Return New DecimalExpression(Function() (Left.Invoke ^ Right.Invoke))
End Function
Public Shared Function Modulo(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke Mod Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return 0
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return 0
Return New DecimalExpression(Function() (Left.Invoke Mod Right.Invoke))
End Function
Public Shared Shadows Function Equals(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(If(Left.Invoke = Right.Invoke, 1, 0))
Return New DecimalExpression(Function() (If(Left.Invoke = Right.Invoke, 1, 0)))
End Function
Public Shared Shadows Function GreaterThan(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(If(Left.Invoke > Right.Invoke, 1, 0))
Return New DecimalExpression(Function() (If(Left.Invoke > Right.Invoke, 1, 0)))
End Function
Public Shared Shadows Function LessThan(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(If(Left.Invoke < Right.Invoke, 1, 0))
Return New DecimalExpression(Function() (If(Left.Invoke < Right.Invoke, 1, 0)))
End Function
Public Shared Shadows Function NotEqual(ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(If(Left.Invoke <> Right.Invoke, 1, 0))
Return New DecimalExpression(Function() (If(Left.Invoke <> Right.Invoke, 1, 0)))
End Function
Public Shared Shadows Function [Or](ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke Or Right.Invoke)
Return New DecimalExpression(Function() (Left.Invoke Or Right.Invoke))
End Function
Public Shared Shadows Function [And](ByVal Left As DecimalExpression, ByVal Right As DecimalExpression) As DecimalExpression
If (Left.IsStatic And Right.IsStatic) Then Return New DecimalExpression(Left.Invoke And Right.Invoke)
If Left.IsStatic AndAlso Left.Invoke = 0 Then Return 0
If Right.IsStatic AndAlso Right.Invoke = 0 Then Return 0
Return New DecimalExpression(Function() (Left.Invoke And Right.Invoke))
End Function
Public Shared Function Func(ByVal Method As [Delegate], ByVal ParamArray Args() As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() CDec(Method.DynamicInvoke(Aggregate I In Args Select CObj(I.Invoke) Into ToArray())))
End Function
Public Shared Function Func(ByVal Method As Func(Of IEnumerable(Of Decimal), Decimal), ByVal ParamArray Args() As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() Method.Invoke(From I In Args Select I.Invoke))
End Function
Public Shared Function Func(ByVal Method As Func(Of Decimal, Decimal), ByVal Argument As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() Method.Invoke(Argument.Invoke))
End Function
Public Shared Function Func(ByVal Method As Func(Of Decimal, Decimal, Decimal), ByVal _
Arg1 As DecimalExpression, ByVal Arg2 As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() Method.Invoke(Arg1.Invoke, Arg2.Invoke))
End Function
Public Shared Function Func(ByVal Method As Func(Of Decimal, Decimal, Decimal, Decimal), _
ByVal Arg1 As DecimalExpression, ByVal Arg2 As DecimalExpression, ByVal Arg3 As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() Method.Invoke(Arg1.Invoke, Arg2.Invoke, Arg3.Invoke))
End Function
Public Shared Function Func(ByVal Method As Func(Of Decimal, Decimal, Decimal, Decimal, Decimal), _
ByVal Arg1 As DecimalExpression, ByVal Arg2 As DecimalExpression, ByVal Arg3 As DecimalExpression, ByVal Arg4 As DecimalExpression) As DecimalExpression
Return New DecimalExpression(Function() Method.Invoke(Arg1.Invoke, Arg2.Invoke, Arg3.Invoke, Arg4.Invoke))
End Function
End Class
Here is an example for using it (I set the countdowntimer's time to 00:00:05(5 seconds)):
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Button1.Enabled = False
CountDownTimer1.Start()
End Sub
' This is called when it finishes the countdown.
Private Sub CountDownTimer1_OnElapsed(ByVal sender As Object, ByVal e As System.EventArgs) Handles CountDownTimer1.OnElapsed
Me.Button1.Enabled = True
End Sub
' This is called whenever it checks if the countdown is done.
Private Sub CountDownTimer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles CountDownTimer1.Tick
Me.Text = Math.Round(Me.CountDownTimer1.TimeLeft.TotalSeconds, 1)
End Sub
Code:
Public Class CountDownTimer
Inherits System.ComponentModel.Component
Sub New()
AddHandler timer.Tick, AddressOf ontick
timer.Start()
InitializeComponent()
End Sub
Sub New(ByVal Time As String)
MyClass.New(TimeSpan.Parse(Time))
End Sub
Sub New(ByVal Time As TimeSpan)
MyClass.New()
Me.Time = Time
End Sub
Public Event OnElapsed As EventHandler
Public Event Tick As EventHandler
Public Property Interval() As Integer
Get
Return timer.Interval
End Get
Set(ByVal value As Integer)
timer.Interval = value
End Set
End Property
Private _time As TimeSpan
Public Property Time() As TimeSpan
Get
Return _time
End Get
Set(ByVal value As TimeSpan)
_time = value
End Set
End Property
Private watch As New Stopwatch
Private timer As New Windows.Forms.Timer() With {.Interval = 100, .Enabled = False}
Private Sub ontick()
If watch.Elapsed >= Time Then
Me.Stop()
RaiseEvent OnElapsed(Me, EventArgs.Empty)
End If
RaiseEvent Tick(Me, EventArgs.Empty)
End Sub
Sub Start()
watch.Start()
timer.Start()
End Sub
Sub [Stop]()
watch.Stop()
timer.Stop()
End Sub
Sub Reset()
watch.Reset()
End Sub
Public ReadOnly Property TimeLeft() As TimeSpan
Get
Return If(watch.Elapsed > Time, New TimeSpan(0), Time - watch.Elapsed)
End Get
End Property
Public ReadOnly Property Elapsed() As TimeSpan
Get
Return If(watch.Elapsed > Time, Time, watch.Elapsed)
End Get
End Property
Public Sub New(ByVal container As System.ComponentModel.IContainer)
MyClass.New()
If (container IsNot Nothing) Then
container.Add(Me)
End If
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
End Class
Feel free to use both, just give credit. Also if anyone can find problems with the calculator, please tell me.

