Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 遍历计时器,然后获取它们的名称_Vb.net_Timer - Fatal编程技术网

Vb.net 遍历计时器,然后获取它们的名称

Vb.net 遍历计时器,然后获取它们的名称,vb.net,timer,Vb.net,Timer,是的,通过花时间进行研究,我意识到 计时器是一个组件而不是控件,因此它不会位于 控制集合。在这种情况下,最好不要这样做 使用公共按钮单击处理程序,因为它不会简化 任何东西() 但是,我能做些什么来改变我的现状吗 我想要的是,每当用户单击一个按钮(我有许多按钮)时,它将确定该按钮的状态是Start还是Stop,如果是Stop,它应该Start 停止和启动对应计时器,按钮的数量对应计时器的数量 通过创建这样的函数,我可以轻松地将它们链接起来 Function isBTNStatusEnabled(s

是的,通过花时间进行研究,我意识到

计时器是一个组件而不是控件,因此它不会位于 控制集合。在这种情况下,最好不要这样做 使用公共按钮单击处理程序,因为它不会简化 任何东西()

但是,我能做些什么来改变我的现状吗

我想要的是,每当用户单击一个按钮(我有许多按钮)时,它将确定该按钮的状态是
Start
还是
Stop
,如果是
Stop
,它应该
Start

停止和启动对应计时器,按钮的数量对应计时器的数量

通过创建这样的函数,我可以轻松地将它们链接起来

Function isBTNStatusEnabled(sender As Object) As Boolean
    Dim result As Boolean = False
    Dim btnStatus As Button = DirectCast(sender, Button)
    Dim btnStatusNumber As String = btnStatus.Name.Substring(btnStatus.Name.Length - 1)

    Console.WriteLine("Found the " & btnStatus.Name)
    If btnStatus.Text = "Start" Then
        btnStatus.Text = "Stop"
        result = True
        btnStatus.BackColor = Color.Red
    Else
        btnStatus.Text = "Start"
        result = False
        btnStatus.BackColor = SystemColors.Control
    End If

    For Each frmTesterObjects As Object In Me.components.Components
        If TypeOf frmTesterObjects Is Timer And DirectCast(frmTesterObjects, Timer).Tag.ToString = "tmrString" & btnStatusNumber Then
            'what to do 
            Console.WriteLine("Timer name: " & DirectCast(frmTesterObjects, Timer).Tag.ToString)
        End If
    Next frmTesterObjects

    Return result
End Function
我的问题是这部分代码

 If TypeOf frmTesterObjects Is Timer And DirectCast(frmTesterObjects, Timer).Tag.ToString = "tmrString" & btnStatusNumber Then
   Console.WriteLine("Timer name: " & DirectCast(frmTesterObjects, Timer).Tag.ToString)
 End If

我试图通过遍历表单中的所有对象来获取计时器的名称。通过正确命名,我可以轻松地对所有对象进行分组,例如在
set1
中,我有
btnStatus1
tmrString1
,然后在
set2
中,我有
btnStatus2
tmrString2
,只有最后一个数字字符串发生了变化。

我刚刚简化了您的代码。这是:

   For Each x In Me.components.Components.OfType(Of Timer)()
        If x.Tag = "tmrString" & btnStatusNumber Then
            Console.WriteLine("Timer name: " & x.Tag)
        End If
    Next
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim parts =
    {
        New With {.Button = Button1, .NumericUpDown = NumericUpDown1, .TextBox = TextBox1, .Port = 1},
        New With {.Button = Button2, .NumericUpDown = NumericUpDown2, .TextBox = TextBox2, .Port = 2},
        New With {.Button = Button3, .NumericUpDown = NumericUpDown3, .TextBox = TextBox3, .Port = 3}
    }

    Dim query =
        From p In parts
        Select
            Observable _
                .FromEventPattern(Sub(h) AddHandler p.Button.Click, h, Sub(h) RemoveHandler p.Button.Click, h) _
                .ObserveOn(Me) _
                .Do(Sub(ep)
                        Dim start = p.Button.Text = "Start"
                        p.Button.Text = If(start, "Stop", "Start")
                        p.Button.BackColor = If(start, Color.Red, SystemColors.Control)
                        p.NumericUpDown.Enabled = Not start
                        p.TextBox.Enabled = Not start
                    End Sub) _
                .Select(Function(ep) _
                    Observable _
                        .Interval(TimeSpan.FromSeconds(p.NumericUpDown.Value)) _
                        .Select(Function(n) New With {p.TextBox.Text, p.Port}) _
                        .TakeWhile(Function(x) p.Button.Text = "Stop")) _
                .Switch()

    query _
        .Merge() _
        .ObserveOn(Me) _
        .Subscribe(
            Sub(x)
                TextBox4.Text = TextBox4.Text + String.Format("Text ""{0}"" on Port ""{1}""{2}", x.Text, x.Port, Environment.NewLine)
            End Sub)

End Sub

现在您所要做的就是匹配每个
计时器的
标记
,该标记对应于其
名称

,我几乎总是发现,如果继续维护/修改表单,在运行时按名称搜索组件最终将失败。在我看来,确保进行编译时检查要好得多

我将改为执行以下代码:

Function isBTNStatusEnabled(sender As Object) As Boolean

    Dim button2Timer = New Dictionary(Of Button, Timer) From
        {{Button1, Timer1}, {Button2, Timer2}, {Button3, Timer3}}

    Dim result As Boolean = False
    Dim btnStatus As Button = DirectCast(sender, Button)

    Console.WriteLine("Found the " & btnStatus.Name)
    If btnStatus.Text = "Start" Then
        btnStatus.Text = "Stop"
        result = True
        btnStatus.BackColor = Color.Red
    Else
        btnStatus.Text = "Start"
        result = False
        btnStatus.BackColor = SystemColors.Control
    End If

    Console.WriteLine("Timer name: " & button2Timer(btnStatus).Tag.ToString())

    Return result

End Function
字典(按钮、计时器)
硬编码映射,因此无需搜索
计时器。这也减轻了对按钮和计时器实际命名和标记的需要


只是为了好玩,我试着根据你对我对这个问题的评论的回答来实现你的完整解决方案。这是:

   For Each x In Me.components.Components.OfType(Of Timer)()
        If x.Tag = "tmrString" & btnStatusNumber Then
            Console.WriteLine("Timer name: " & x.Tag)
        End If
    Next
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim parts =
    {
        New With {.Button = Button1, .NumericUpDown = NumericUpDown1, .TextBox = TextBox1, .Port = 1},
        New With {.Button = Button2, .NumericUpDown = NumericUpDown2, .TextBox = TextBox2, .Port = 2},
        New With {.Button = Button3, .NumericUpDown = NumericUpDown3, .TextBox = TextBox3, .Port = 3}
    }

    Dim query =
        From p In parts
        Select
            Observable _
                .FromEventPattern(Sub(h) AddHandler p.Button.Click, h, Sub(h) RemoveHandler p.Button.Click, h) _
                .ObserveOn(Me) _
                .Do(Sub(ep)
                        Dim start = p.Button.Text = "Start"
                        p.Button.Text = If(start, "Stop", "Start")
                        p.Button.BackColor = If(start, Color.Red, SystemColors.Control)
                        p.NumericUpDown.Enabled = Not start
                        p.TextBox.Enabled = Not start
                    End Sub) _
                .Select(Function(ep) _
                    Observable _
                        .Interval(TimeSpan.FromSeconds(p.NumericUpDown.Value)) _
                        .Select(Function(n) New With {p.TextBox.Text, p.Port}) _
                        .TakeWhile(Function(x) p.Button.Text = "Stop")) _
                .Switch()

    query _
        .Merge() _
        .ObserveOn(Me) _
        .Subscribe(
            Sub(x)
                TextBox4.Text = TextBox4.Text + String.Format("Text ""{0}"" on Port ""{1}""{2}", x.Text, x.Port, Environment.NewLine)
            End Sub)

End Sub
我在所有事件处理和计时器中都使用了微软的反应式框架。你只需要在你的应用程序中加入“Rx WinForms”就可以使用它

您将看到,
部分
包含按钮列表、数字向上/向下、文本框和端口号

query
获取这些部分并为按钮单击创建处理程序。根据按钮内的文本,它根据数字上/下控件和文本框启动计时器。查询只是以
{.Text=“Foo”,.Port=1}
的形式生成一个值流<代码>查询
还使用
.Do(…)
操作符在计时器运行时更新UI

最后,
.Subscribe(…)
代码获取这些值,并在我的应用程序中,将它们添加到表单上的文本框中,以便我可以查看所有输出

下面是我正在使用的表单示例:


我希望您对此感兴趣。

您想改用
Tag
吗?如果
Tag
可以帮助我获取计时器的名称,那就可以了。:)在我的代码中,我只是尝试使用
标记
,因为有人建议使用它。在您的情况下,您的代码使用
标记
看起来很好。您现在所要做的就是分别更改计时器的
标记。您可以发布一个答案吗?从Button派生您自己的类,添加一个属性来存储计时器。哦,
您现在所要做的就是将每个计时器的标记与其名称相匹配。
这是我不清楚的部分。对不起,你能提供一个例子吗?你的
定时器是在
设计时创建的吗?嗯,不确定?我拖放它们。重命名每个计时器上的
设计时间
,单击每个
计时器
,您可以看到其
属性
,其中有一个
标记
。将其更改为您的
计时器的名称。哦,很高兴知道。很抱歉出现错误,我尚未测试该代码。快乐编码:)太棒了!非常感谢你!是的,这是我感兴趣的!我现在正在研究nuget,它现在起作用了!我的感谢还不足以表达我的感激之情。一个非常棒的代码!