#vb.net
#vb.net
Вопрос:
Для моего проекта у меня есть много таймеров, которые управляют замиранием медиаплеера, у каждого таймера есть имя Fade_
, а затем уникальный индексный номер, начинающийся с 0
, т. е. Fade_0
, Fade_1
Fade_2
и т. д.
Я хочу найти простой способ ссылаться на эти таймеры, чтобы я мог их запускать, однако я не могу найти простой способ сделать это.
Я пробовал следующее, но таймеры не классифицируются как элементы управления, и поэтому это не работает.
Dim MyFadeTimer As Timer = Controls.Find("Fade_" amp; KeyIndex, True)(0)
MyFadeTimer.Enabled = True
Как я могу добиться подобного?
РЕДАКТИРОВАТЬ: используя глобальный список pf Dim FadeTimers As New List(Of Timer)
, я могу ссылаться на них, но при заполнении списка с помощью Dim FadeTimers As New List(Of Timer)({Fade_0, Fade_1, Fade_2...})
я получаю сообщение об ошибке, в котором говорится, что в списке ничего нет, когда я вызываю его с помощью FadeTimers(KeyIndex).start()
. Однако, когда я заполняю список, используя `FadeTimers.AddRange({Fade_0, Fade_1, …}) это работает?
Почему первый метод заполнения списка не работает, а второй работает?
Комментарии:
1. Как вы ссылаетесь на них в принципе, если они не являются элементами управления?
2. Вы не можете добиться аналогичной вещи, потому что нет подобной коллекции, в которую
Timers
добавляются. Если вам нужна коллекция, содержащая вашTimers
, вам нужно ее создать. Затем вы можете получить его по индексу,Tag
или вы можете использоватьDictionary
. Тем не менее, как вы думаете, сколькоTimers
вам нужно? В большинстве случаев, когда я видел, как люди используют несколько, им на самом деле нужен только один. Нет причин, по которым вы не можетеTick
использовать его несколько раз через разные интервалы.3. @jmcilhinney Мой проект представляет собой виртуальное пианино, и мне нужно использовать таймер, чтобы отключить звук после отпускания клавиши. Поскольку на моем пианино вы можете нажимать более одной клавиши одновременно, мне нужно иметь таймер для каждой клавиши.
4. @GSerg я в замешательстве, что вы имеете в виду?
5. Да, вы должны использовать AddRange() . Порядок имеет значение, инициализация списка выполняется слишком рано. Прежде чем конструктор смог завершить вызов метода InitializeComponent() . Таким образом, переменные по-прежнему ничего.
Ответ №1:
Вы могли бы добавить их все вручную в List(Of Timer)
:
Public Class Form1
Private KeyIndex As Integer
Private Timers As New List(Of Timer)({Fade_0, Fade_1, Fade_2, Fade_3, Fade_4})
Private Sub Foo()
Timers(KeyIndex).Start()
End Sub
End Class
Вариантом может быть заполнение списка из события Load():
Public Class Form1
Private KeyIndex As Integer
Private FadeTimers As New List(Of Timer)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FadeTimers.AddRange({Fade_0, Fade_1, ...})
End Sub
End Class
Если вы не хотите перечислять их все, вы можете использовать отражение, чтобы найти их. Обратите внимание, что мы должны добавить символ подчеркивания «_» перед именем таймера. Это делается только один раз, при загрузке формы:
Public Class Form1
Private KeyIndex As Integer
Private Timers As New List(Of Timer)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fi As Reflection.FieldInfo
Dim flags As Reflection.BindingFlags = Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic
For i As Integer = 0 To 4 ' <-- Change the 4 to the highest number of your Timers
fi = Me.GetType.GetField("_Fade_" amp; i, flags)
If Not IsNothing(fi) Then
Timers.Add(fi.GetValue(Me))
End If
Next
End Sub
End Class
Затем вы можете получить доступ к таймерам по индексу, как в первом примере:
Timers(KeyIndex).Start()
Комментарии:
1. Привет, я попробовал первый предложенный вами метод, но теперь я получаю сообщение об ошибке при вызове . Start(): «System.NullReferenceException: «Ссылка на объект не установлена для экземпляра объекта». System. Коллекции. Generic.List<T>.this[int].get ничего не вернуло.» и я не знаю почему? Я сделал именно так, как вы сказали, и создал новый список таймеров.
2. Обновите свой пост выше своим новым кодом, и мы поможем вам разобраться.
3. Любопытно, что если я заполняю список, используя
.AddRange
then, он работает, но не сPrivate Timers As New List(Of Timer)({Fade_0, Fade_1, Fade_2, Fade_3, Fade_4})
4. Я не уверен, почему первый синтаксис не сработал для вас. Это отлично сработало для меня в моем тестировании. Я заполнил его, извлек таймер по значению индекса и активировал его.
5. Я понял это, чтобы не использовать
.AddRange
, мне просто нужно было не использовать список в качестве глобальной переменной, что, похоже, сработало для меня