[VB2010] Timer per Buttonclick

06/28/2014 18:29 ChilloutFuzi#1
Hey,
Ich hab ma eine Frage und zwar wollte ich wissen ob es möglich ist in Visual Basic einen Button zu Programmieren das er einen vb.Timer erstellt und man von diesem die Funktion festlegen kann und am Schluss sollte es so aussehen das man unendlich oft einen vb.Timer erstellen kann.
06/28/2014 19:13 Ravenstorm#2
Einen VB.timer oder einen Uhrzeitentimer ?
06/28/2014 19:31 ChilloutFuzi#3
einen VB.timer
06/29/2014 11:19 stotterer09#4
wenn du den Timer als Attribut der Klasse haben willst dann einfach
Code:
Public Class Form1

Dim timer(100) As Timer
Dim i As int= 0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer(i) = new timer
i = i+1 
end sub
End Class
Eine Sache ist blöd daran man muss vorher wissen wv Timer man erstellen will
Um das zu umgehen müsstest du mit list arbeiten
06/29/2014 12:35 th0rex#5
Quote:
Originally Posted by stotterer09 View Post
wenn du den Timer als Attribut der Klasse haben willst dann einfach
Code:
Public Class Form1

Dim timer(100) As Timer
Dim i As int= 0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer(i) = new timer
i = i+1 
end sub
End Class
Eine Sache ist blöd daran man muss vorher wissen wv Timer man erstellen will
Um das zu umgehen müsstest du mit list arbeiten
Muss man nicht wissen und man muss nicht mit Listen arbeiten.
Code:
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim timer As New Timer()
        AddHandler timer.Tick, AddressOf Timer_Tick
        timer.Interval = 1337
        timer.Start()
        Container.Add(timer)
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        'Add Code here.
    End Sub
End Class
Edit: Außerdem was meinst du mit Timer als Attribut der Klasse ?
06/29/2014 14:03 stotterer09#6
Quote:
Originally Posted by omitma View Post
Muss man nicht wissen und man muss nicht mit Listen arbeiten.
Code:
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim timer As New Timer()
        AddHandler timer.Tick, AddressOf Timer_Tick
        timer.Interval = 1337
        timer.Start()
        Container.Add(timer)
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        'Add Code here.
    End Sub
End Class
Edit: Außerdem was meinst du mit Timer als Attribut der Klasse ?

Ein Attribut ist eine Eigenschaft einer Klasse:
gehen wir davon aus wir haben eine Klasse Mensch dann ist ein Attribut von dem das Geschlecht

In meinem Fall ist der Timer ein Attribut der Klasse Form1 -> Man kann in der ganzen Klasse drauf zugreifen
In deinem Fall ist der Timer nur Lokal in der Methode -> Man kann eigentlich nur in der Methode drauf zugreifen

Somit haben beide Codes ihre schwächen

Bei meinem Code muss man vorher wissen wv man haben will
das hab ich dazu geschrieben um zu zeigen dass mein Code nicht super toll ist sondern nur eine Art es möglichst einfach zu machen
06/29/2014 14:35 th0rex#7
Quote:
Originally Posted by stotterer09 View Post
Ein Attribut ist eine Eigenschaft einer Klasse:
gehen wir davon aus wir haben eine Klasse Mensch dann ist ein Attribut von dem das Geschlecht

In meinem Fall ist der Timer ein Attribut der Klasse Form1 -> Man kann in der ganzen Klasse drauf zugreifen
In deinem Fall ist der Timer nur Lokal in der Methode -> Man kann eigentlich nur in der Methode drauf zugreifen

Somit haben beide Codes ihre schwächen

Bei meinem Code muss man vorher wissen wv man haben will
das hab ich dazu geschrieben um zu zeigen dass mein Code nicht super toll ist sondern nur eine Art es möglichst einfach zu machen
Stimmt leider nicht. Ein Attribut ist sowas hier:
Code:
<Conditional("DEBUG")> 
Sub TraceMethod()
End Sub
Du redest von Membern (oder auch Variablen) der Klasse.


Außerdem ist mein Timer zwar nur Lokal, aber
Code:
Container.Add(timer)
fügt ihn den Controls hinzu, womit er sogar disposed wird, was bei deinem nicht der Fall ist.
Man kann auf jeden meiner Timer zugreifen.
Code:
For Each currentTimer As Timer In (From item As Object In Container.Components Where item Is timer).Cast(Of Timer)()
            'Oder was auch immer damit gemacht werden soll.
            MessageBox.Show(currentTimer.Interval.ToString())
        Next
Und du übergibst deinem Timer keine Funktion für das Tick Event wodurch er nichst machen wird.

Wenn man nicht Container benutzen möchte (oder kann lol. mir ist auch grade aufgefallen, dass der bei mir null ist. kp warum) kann man das ganze auch so machen:
Code:
Public Class Form1
    Private ReadOnly _allTimers As List(Of Timer) = New List(Of Timer)()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim timer As New System.Windows.Forms.Timer()
        AddHandler timer.Tick, AddressOf Timer_Tick
        timer.Interval = 1337
        timer.Start()
        _allTimers.Add(timer)
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    End Sub
End Class
So kann man dann durch alle Timer loopen:
Code:
        For Each currentTimer As Timer In _allTimers
            'Mach was damit.
        Next
Falls der Topic Ersteller nicht nur Timer, sondern auch andere Objekte zur Laufzeit erstellen möchte, ist hier ein kleines Beispiel, wie man das lösen könnte ohne den Container zu nutzen:
Code:
Option Strict Off
Public Class Form1
    Private ReadOnly _allComponents As List(Of Object) = New List(Of Object)()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim tmpTimer As New System.Windows.Forms.Timer()
        AddHandler tmpTimer.Tick, AddressOf Timer_Tick
        tmpTimer.Interval = 1337
        tmpTimer.Start()
        _allComponents.Add(tmpTimer)

        Dim nurEinBeispielFürEinAnderesControl As New TextBox()
        nurEinBeispielFürEinAnderesControl.Text = "Hallo :)"
        _allComponents.Add(nurEinBeispielFürEinAnderesControl)
    End Sub

    Private Sub ShowIntervalOfAllTimers()
        For Each currentTimer As Timer In _allComponents.OfType(Of Timer)()
            MessageBox.Show(currentTimer.Interval.ToString())
        Next
    End Sub

    Private Sub ShowTextOfAllTextBoxes()
        For Each currentTextBox As TextBox In _allComponents.OfType(Of TextBox)()
            MessageBox.Show(currentTextBox.Text)
        Next
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    End Sub
End Class
Edit: @Chillout dann nutz halt die Version mit der Liste. Bei mir ist der auch null. Hatte den Code halt vorher nicht getestet, weil ich davon ausgegangen bin, dass der Container dafür da ist alle Controls zu speichern.
06/29/2014 14:46 ChilloutFuzi#8
Hab das jetzt im Button:
Quote:
Dim timer As New System.Windows.Forms.Timer()
AddHandler timer.Tick, AddressOf Timer_Tick
timer.Interval = 1337
timer.Start()
_allTimers.Add(timer)
und
das in der Form:
Quote:
Private ReadOnly _allTimers As List(Of Timer) = New List(Of Timer)()
und
das als Timer:
Quote:
Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

End Sub
Funktioniert thx
___________________________________
Eine Frage hätte ich noch gibts eine möglichkeit die aktivien Timer zu speichern und beim nächsten Startvorgang der Form wieder zu starten ?
Ich hab es jetzt mit einer For schleife und my.settings gemacht die settings lass ich mit count zählen aber es werden nicht alle timer geladen.
06/29/2014 16:08 stotterer09#9
Quote:
Originally Posted by omitma View Post
Stimmt leider nicht. Ein Attribut ist sowas hier:
Code:
<Conditional("DEBUG")> 
Sub TraceMethod()
End Sub
Du redest von Membern (oder auch Variablen) der Klasse.


Außerdem ist mein Timer zwar nur Lokal, aber
Code:
Container.Add(timer)
fügt ihn den Controls hinzu, womit er sogar disposed wird, was bei deinem nicht der Fall ist.
Man kann auf jeden meiner Timer zugreifen.
Code:
For Each currentTimer As Timer In (From item As Object In Container.Components Where item Is timer).Cast(Of Timer)()
            'Oder was auch immer damit gemacht werden soll.
            MessageBox.Show(currentTimer.Interval.ToString())
        Next
Und du übergibst deinem Timer keine Funktion für das Tick Event wodurch er nichst machen wird.

Wenn man nicht Container benutzen möchte (oder kann lol. mir ist auch grade aufgefallen, dass der bei mir null ist. kp warum) kann man das ganze auch so machen:
Code:
Public Class Form1
    Private ReadOnly _allTimers As List(Of Timer) = New List(Of Timer)()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim timer As New System.Windows.Forms.Timer()
        AddHandler timer.Tick, AddressOf Timer_Tick
        timer.Interval = 1337
        timer.Start()
        _allTimers.Add(timer)
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    End Sub
End Class
So kann man dann durch alle Timer loopen:
Code:
        For Each currentTimer As Timer In _allTimers
            'Mach was damit.
        Next
Falls der Topic Ersteller nicht nur Timer, sondern auch andere Objekte zur Laufzeit erstellen möchte, ist hier ein kleines Beispiel, wie man das lösen könnte ohne den Container zu nutzen:
Code:
Option Strict Off
Public Class Form1
    Private ReadOnly _allComponents As List(Of Object) = New List(Of Object)()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim tmpTimer As New System.Windows.Forms.Timer()
        AddHandler tmpTimer.Tick, AddressOf Timer_Tick
        tmpTimer.Interval = 1337
        tmpTimer.Start()
        _allComponents.Add(tmpTimer)

        Dim nurEinBeispielFürEinAnderesControl As New TextBox()
        nurEinBeispielFürEinAnderesControl.Text = "Hallo :)"
        _allComponents.Add(nurEinBeispielFürEinAnderesControl)
    End Sub

    Private Sub ShowIntervalOfAllTimers()
        For Each currentTimer As Timer In _allComponents.OfType(Of Timer)()
            MessageBox.Show(currentTimer.Interval.ToString())
        Next
    End Sub

    Private Sub ShowTextOfAllTextBoxes()
        For Each currentTextBox As TextBox In _allComponents.OfType(Of TextBox)()
            MessageBox.Show(currentTextBox.Text)
        Next
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    End Sub
End Class
Edit: @Chillout dann nutz halt die Version mit der Liste. Bei mir ist der auch null. Hatte den Code halt vorher nicht getestet, weil ich davon ausgegangen bin, dass der Container dafür da ist alle Controls zu speichern.
du hast recht damit dass deine Timer zugreifbar sind


und mit List wie du es bei deinem zweiten code gemacht hast ist es am schönsten

und ja ich habe meinem Timer keine Funktion für das Tick Event übergeben

ich gebs ja zu mein code war schrott

achja
Attribute ist der deutsche Begriff für Member(steht jedenfalls so auf wikipedia)
http://de.wikipedia.org/wiki/Objekto...g#Terminologie
06/29/2014 17:46 th0rex#10
Quote:
Originally Posted by ChilloutFuzi View Post
Eine Frage hätte ich noch gibts eine möglichkeit die aktivien Timer zu speichern und beim nächsten Startvorgang der Form wieder zu starten ?
Ich hab es jetzt mit einer For schleife und my.settings gemacht die settings lass ich mit count zählen aber es werden nicht alle timer geladen.
Code:
Option Strict Off

Imports System.IO
Imports System.Reflection

Public Class Form1
    Private ReadOnly _allComponents As List(Of Object) = New List(Of Object)()

    Private Sub btnAddTimer_Click(sender As Object, e As EventArgs) Handles btnAddTimer.Click
        Dim tmpTimer As New System.Windows.Forms.Timer()
        AddHandler tmpTimer.Tick, AddressOf Timer_Tick
        tmpTimer.Interval = 1337
        tmpTimer.Start()
        _allComponents.Add(tmpTimer)
    End Sub

    Private Iterator Function GetAllTimers() As IEnumerable(Of Timer)
        For Each currentComponent As Timer In _allComponents.OfType(Of Timer)()
            Yield currentComponent
        Next
    End Function

    Private Sub SaveState(ByVal timers As List(Of Timer), ByVal methodName As String)
        Dim stream As New StreamWriter(Path.Combine(Environment.CurrentDirectory, "timers.txt"), False) ' Überschreibt die alte datei. Wenn es true ist kackt LoadTimers ab.'
        stream.WriteLine(methodName)
        For Each currentTimer In timers
            stream.WriteLine(currentTimer.Interval)
            stream.WriteLine(currentTimer.Enabled)
            stream.Flush()
        Next
        stream.Close()
    End Sub

    Private Sub LoadTimers()
        Dim stream As New StreamReader(Path.Combine(Environment.CurrentDirectory, "timers.txt"))
        Dim methodName = stream.ReadLine()
        Dim method As MethodInfo
        Try
            method = Me.GetType().GetMethod(methodName)
        Catch
            Return
        End Try
        If method Is Nothing Then
            Return
        End If
        Dim interval As Int32 = 0
        Dim isTimerEnabled As Boolean = False
        While Not stream.EndOfStream()
            Dim currentElement = stream.ReadLine()
            If interval = 0 AndAlso Int32.TryParse(currentElement, interval) Then
                ' Da wir hier nur den ersten Teil auslesen den wir für den Timer brauchen, müssen wir hier nichst machen.'
            ElseIf Boolean.TryParse(currentElement, isTimerEnabled) Then
                ' Mach nen neuen timer, weil enabled das letzte element ist, was für den MOMENTANEN timer in die datei geschrieben wurde'
                Dim timer As New Timer()
                AddHandler timer.Tick, Function(sender, e)
                                           InvokeWrapper(method, Me, sender, e) 'ich habe ein paar andere Wege wie method.CreateDelegate probiert nur die wollten nicht wirklich.'
                                       End Function
                timer.Interval = interval
                timer.Start()
                timer.Enabled = isTimerEnabled
                _allComponents.Add(timer)
            End If
        End While
    End Sub

    Private Sub InvokeWrapper(method As MethodInfo, instance As Object, ParamArray arguments As Object())
        method.Invoke(instance, arguments)
    End Sub

    Private Sub ShowIntervalOfAllTimers()
        For Each currentTimer As Timer In _allComponents.OfType(Of Timer)()
            MessageBox.Show(currentTimer.Interval.ToString())
        Next
    End Sub

    Private Sub ShowTextOfAllTextBoxes()
        For Each currentTextBox As TextBox In _allComponents.OfType(Of TextBox)()
            MessageBox.Show(currentTextBox.Text)
        Next
    End Sub

    Public Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    End Sub

    Private Sub btnSaveTimers_Click(sender As Object, e As EventArgs) Handles btnSaveTimers.Click
        SaveState(GetAllTimers().ToList(), "Timer_Tick")
    End Sub

    Private Sub btnLoadTimers_Click(sender As Object, e As EventArgs) Handles btnLoadTimers.Click
        LoadTimers()
    End Sub
End Class
06/29/2014 18:29 ChilloutFuzi#11
Das muss doch aber einfacher gehen
07/10/2014 21:32 TheBeanjay#12
Einfach nen Timer im Entwurf hinzufügen und dann einfach im Button Click Event Timer.Start?

Das ist wirklich der aller einfachste Weg :D
07/11/2014 15:39 th0rex#13
Er möchte eine zur compile zeit unbestimmte Anzahl an Timern erstellen können.
07/25/2014 19:49 TheBeanjay#14
Achso, dann musst du wohl den harten Weg gehen ^^