在我的任务中有奇怪的行为,但没有完成。我一直使用这个,但我想它因为我传递给它的是迭代与形式 - 改变选择和刷新一些列表框可能因此它的堆栈,但我不确定。让我们看看代码:
这是我希望在任务中运行的子项:
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
Unselect:
For i As Integer = 0 To LB_Sentences.SelectedItems.Count - 1
Dim sKey As ListBoxItem
sKey = LB_Sentences.SelectedItems(i)
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
sKey.IsSelected = False
LB_Sentences.Refresh()
GoTo Unselect
End If
Next
End Sub
我把它放到这样的任务中:
Dim pic As New FrmCircularProgress(eCircularProgressType.Line)
Dim work As Task = Task.Factory.StartNew(Sub()
'--Run lenghty task UnselectExistingConnectionsItems()
'--Close form once done (on GUI thread)
pic.Invoke(New Action(Sub() pic.StopCircular()))
pic.Invoke(New Action(Sub() pic.Close()))
End Sub)
'--Show the form
pic.ShowDialog()
Task.WaitAll(work)
和FrmCircularProgress只是形式(我几乎在任何地方使用它,我必须等待用户等待它的工作除了这个特殊情况):
Public Class FrmCircularProgress
Sub New(progressType As DevComponents.DotNetBar.eCircularProgressType)
InitializeComponent()
CircularProgress1.ProgressBarType = progressType
StartCircular()
End Sub
Public Sub StartCircular()
Me.CircularProgress1.IsRunning = True
End Sub
Public Sub StopCircular()
Me.CircularProgress1.IsRunning = False
End Sub
End Class
什么可能是错的?是因为程序与listbox和combobxes交互?如果是这样如何解决这个问题,我会阅读有关调用listbox和comboboxes的内容,但不知道如何解决这个问题。
修改 我认为除了这些方面:
sKey.IsSelected = False
LB_Sentences.Refresh()
我必须做那些:
LB_Sentences.Invoke(Sub() sKey.IsSelected = False
End Sub)
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh()
End Sub)
因为我处在不同的线程中。不知怎的,我不知道如何转换这些行:
SubSectionId = CbSubSections.SelectedValue
SubSubKategorieId = CbSubSubKategorie.SelectedValue
可能还需要调用循环。等待你的帮助。
答案 0 :(得分:0)
有一条规则说"唯一可以修改窗口中控件的线程是创建窗口的线程"。尝试修改窗口中某些内容的任何其他线程都将生成跨线程调用异常。
因此,在第一次编辑中,你做对了,你必须调用函数。
但是,这并不能解决您未完成任务的问题。
我认为执行sKey.IsSelected = False
并不会取消选择ListBox中的任何内容,因此会导致无限循环......另外,Goto
语句是非常糟糕的编程习惯,不应该使用。总有另一种解决方案可以让您的代码更容易调试/维护/读取......
ListBoxItem
不是.Net Framework中存在的类型。所以要么你创造了这个课程,要么是其他的东西(我不知道是什么......)
您可以采取以下措施解决问题:
这使得您的代码就像这样(并且删除了您在代码中不想要的那个丑陋的标签和Goto)......
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
'We create an array to remind our initial selection
Dim sel = New Integer(LB_Sentences.SelectedItems.Count - 1) {}
LB_Sentences.SelectedIndices.CopyTo(sel, 0)
For i = 0 To sel.Length - 1
Dim sKey As ListBoxItem
'We get our selected item
sKey = LB_Sentences(sel(i))
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
'We must remove it from the selection
LB_Sentences.Invoke(Sub() LB_Sentences.SelectedItems.Remove(sKey))
End If
Next
'We do the Refresh at the end so we gain some process time...
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh())
End Sub