我在从主窗体中编辑表单中的标签控件的.text属性时遇到了一些麻烦。
这是我想要完成的事情:
当主表单中的程序运行时,标签文本和进度更新应用程序所在的位置和%完成(完成的百分比只是.Value和我放入的数字)
公共类frmMain 昏暗的进展作为frmProgress
Public Sub LoadProgress() 的InitializeComponent() progress =新的frmProgress progress.Show() End Sub
然后我用我想要的形式调用对象
progress.label.text = "stuff"
progress.prgTaskProgress.Value = 25
这......技术上有效。但是它似乎打破了我所有主要表单变量和对象(如文本框)的可用性。例如,我有一个例外,如果你将其中一个文本框留空,那么在加载进度条表单之后它就不会看到文本框的值,所以认为它是空白的并抛出错误。
如果我删除了InitiliazeComponent()调用,我仍然可以更改进度条的.Value,它实际上一直有效我之前只能使用frmProgress.progTaskProgress.Value = 25并且它可以工作。
抱歉得到了主题,如果我删除了初始化,我仍然可以访问进度条没问题,但我的标签的文本值不再更改,应用程序的其余部分运行没有问题。
现在,如果我刚刚启动应用程序,我可能会在主窗体上运行任务并将它们移动到进度条表单,但这是对已经接近完成的应用程序的附加/增强,所以它将是在这一点上做这件事很麻烦。
或者,我可以根据需要使用.visible并隐藏/显示主窗体上的进度条,但我宁愿将其作为自己的窗体。
我倾向于絮絮叨叨,所以我总结一下: - 上面的代码“有效”,但我无法访问主要表单对象内容(如文本框中的文本) - 如果我删除了InitializeComponent(),我仍然可以更改进度条对象,并且正在运行的代码仍然可以访问所有其他主要表单对象,但是更改进度表单上的.text值的功能已经消失。
我希望我能够正确地解释这一点,你可以理解我正在做的事情。
更新: 我发现尝试了一些你发布的解决方案,实际上我的一些陈述是有用的,但我从来没有让他们在那之前做到这一点。
If My.Computer.FileSystem.FileExists(extFilePath + fileXP) Then
fileXPNew = domainName + " " + fileXP
My.Computer.FileSystem.RenameFile(extFilePath + fileXP, fileXPNew)
My.Computer.FileSystem.CopyFile(extFilePath + fileXPNew, modSharePath + fileXPNew, True)
' FAIL progress.lblTaskName.Text = "Processing XP Migration Readiness Report"
Thread.Sleep(15000) ' Pause for OneSync delay
My.Computer.FileSystem.DeleteFile(extFilePath + fileXPNew)
progress.prgTaskProgress.Value = 90
End If
progress.lblTaskName.Text = "Transfer Complete. Closing Processes please wait..."
Thread.Sleep(2000)
progress.prgTaskProgress.Value = 93
Thread.Sleep(2000)
progress.prgTaskProgress.Value = 96
Thread.Sleep(2000)
progress.prgTaskProgress.Value = 99
Thread.Sleep(2000)
progress.prgTaskProgress.Value = 100
' WORKS progress.lblTaskName.Text = "Process Complete. Please verify your OneDrive sync. Resetting application..."
Thread.Sleep(2000)
progress.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
Catch ex As Exception
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
我突出显示了失败和工作的线条虽然网站上的灰色可能有点难以看清。
所有这些都在TRY语句中,对于另一个表单上的标签文本的更改在嵌套在TRY语句中的IF语句中失败,而不是在TRY本身的行中失败。我希望这有道理吗?
我会睡个好觉,希望今晚能够更有意义。
答案 0 :(得分:2)
深入查看InitializeComponent
过程,您将看到它正在初始化主窗体上的所有控件。这只需要从构造函数中完成一次。
您更新进度表单的方法陷入了实施细节。实际上,任何需要更新进度的形式,模块或类的过程都必须根据名称来控制该表单的设置。
您可以定义 更新进度显示,并将详细信息(如何)保留到拥有/的表单中容纳控制。这是通过添加方法并调用它来完成的:
Public Class FormProgress
Public Sub UpdateDisplay(txt as String, v As integer) '?
' the details of which controls are involved
' remain in the form which contains them:
lblProgress.text = txt
progBar.Value = v
End Sub
现在任何表单,模块,类或过程都可以告诉表单实例更新并将详细信息保留在表单中:
frmProgress.UpdateDisplay("sometext", 25)
这种抽象中的值是,如果您更改某些内容(例如添加红黄绿色进度颜色指示符),则只需在一个位置更改代码。
答案 1 :(得分:0)
尝试使用反射。您可以使用下面的函数(SetControlProperty)来更改任何表单上任何控件的任何属性。
这是一个例子(form1)
Option Strict On
Option Explicit On
Option Infer Off
Imports System.Reflection
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Form2.Show()
End Sub
Public Sub SetControlProperty(ControlName As String, propertyName As String, Value As Object)
Dim obj As Control = Me.Controls(ControlName)
If obj Is Nothing Then
MsgBox("Control not found!")
Else
Dim prop As PropertyInfo() = obj.GetType.GetProperties
For Each pi As PropertyInfo In prop
If pi.Name.ToLower = propertyName.ToLower Then
pi.SetValue(obj, Value)
End If
Next
End If
End Sub
End Class
(窗体2)
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form1.SetControlProperty("Button1", "Text", "Hello World!")
End Sub
End Class