Reputation: 23
I'm trying to access Label from another class's method running in background thread with the help of MainWindow Class's Public Shared Sub like this:
Private Delegate Sub ProgressReportInvoker(ByVal progressStr As String)
Public Shared Sub ProgressReport(ByVal progressStr As String)
If MainWindow.Label.Dispatcher.CheckAccess() Then
MainWindow.Label.Content = progressStr
Else
MainWindow.Label.Dispatcher.Invoke(
New ProgressReportInvoker(AddressOf ProgressReport),
progressStr)
End If
End Sub
Call from another class is below:
MainWindow.ProgressReport("Sample text")
But I have this error on "MainWindow.Label":
Reference to a non-shared member requires an object reference.
I noticed that if I declare Label in MainWindow.g.i.vb as Public Shared than error is gone:
#ExternalSource ("..\..\MainWindow.xaml", 11)
<System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")>
Public Shared WithEvents Label As System.Windows.Controls.Label
#End ExternalSource
But this file is generated automatically from the *.XAML file so it takes previous look when I compile the code.
Is there any way to make control shared in *.XAML file or may be there are any alternatives of making my task possible?
Upvotes: 2
Views: 352
Reputation: 169160
You should access the instance of the MainWindow
and not the type itself:
Public Shared Sub ProgressReport(ByVal progressStr As String)
Dim mainWindow = Application.Current.Windows.OfType(Of MainWindow).FirstOrDefault()
If mainWindow.Label.Dispatcher.CheckAccess() Then
mainWindow.Label.Content = progressStr
Else
mainWindow.Label.Dispatcher.Invoke(
New ProgressReportInvoker(AddressOf ProgressReport),
progressStr)
End If
End Sub
I tried this before but problem is in multitasking. I can't access the form from another thread without some special moves which I don't know about
You can only access a UI control in the thread on which it was originally created:
Application.Current.Dispatcher.BeginInvoke(New Action(Sub()
Dim mainWindow = Application.Current.Windows.OfType(Of MainWindow).FirstOrDefault()
mainWindow.Label.Content = progressStr
End Sub))
Upvotes: 1
Reputation: 1673
It is very bad practice to use anything global (shared/static). Use instance of class or other mechanism (Dependency Injection, messaging, events, etc.) for communication between independent classes.
Upvotes: 0