views:

66

answers:

1

I have a WPF application with form that has a textbox named "txtStatusWindow". I also have a vb.net class handed to me by a co-worker that needs to be called and executed by the code in my application code-behind. My co-worker insists that I will need to use common .net events to update the textbox on my form.

The separate vb.net class:

Public Class globalclass

Public Event txtStatusWindow(ByVal Text As String)


Public Sub InitializeProgram()
    RaiseEvent txtStatusWindow("Updating something.")
    System.Threading.Thread.Sleep(2000)
    RaiseEvent txtStatusWindow("Updating something else.")
    System.Threading.Thread.Sleep(2000)
    RaiseEvent txtStatusWindow("Updating something other than else.")
    System.Threading.Thread.Sleep(2000)
    RaiseEvent txtStatusWindow("Updating something other than the else stuff.")
    System.Threading.Thread.Sleep(2000)
End Sub

End Class

I need to be able to call the sub "InitializeProgram()" from my code-behind, and it needs to be able to update "txtStatusWindow.text" as it runs.

I told him that the updating of the text box can be done with data-binding, but I don't know how to integrate a separate class like this into my project, how to call methods in it, or how to cause it to update my text blocks through data binding.

I also suggested that the methods in this class aren't optimal for connecting to the WPF project anyway, but he just wrote it as an example to discover how to connect the two projects.

Eventually, I will need to integrate classes like these that will be running separate threads to update their data from a dynamic source, and cause many controls to update in my application.

So far, the only way we have been able to get this to work from my code-behind is this:

    Partial Public Class SplashScreen

Dim NewText as String

    Public WithEvents Globals As globalclass = New globalclass
    Public Delegate Sub StringDelegate(ByVal Text As String)
    Public SplashText As String

Public Sub New()
    MyBase.New()
    Me.InitializeComponent()
    Me.Show()
    Globals.InitializeProgram()

End Sub

Public Sub UpdateSplashscreenHandler(ByVal Text As String) Handles Globals.UpdateSplashScreen

    StatusWindowText.Text = Text

End Sub

Notwithstanding the fact that the WPF screen "freezes" until the "globalclass InitializeProgram" method completes (txtStatusWindow.Text does not update while sub without using the esoteric "refresh" extension...), I fully believe we are going about this the wrong way.

There are precious few examples out there concerning the integration and then binding to objects in existing code. Thanks for examining our little quandary.

A: 

If this status window is in XAML and the status window is a UserControl, then add a StatusText dependency property to the status window. Then, in the XAML you can bind to the value of that property with something like:

<UserControl x:Name="MyStatusWindow" ...>
  <TextBlock Text="{Binding Path=StatusText, ElementName=MyStatusWindow}" />
</UserControl>

Then, from your event, just update the value of that StatusText property.

(Is that even close to what you were asking?)

Also, about that freezing: Instead of doing that updating in the constructor of that class, you might want to do it from the Loaded event of that control. It will still be freezing, though, unless you move it to a separate thread. Right now, that's happening on the same thread that the UI message pump is running on. This is the Dispatcher for that UI.

MojoFilter
The "StatusWindowText" object is just a common textbox, so it has a dependency property. The reason the routine fails turns out to be in the way we were calling the sub in the class "globalclass". The sub would not update the calling form "SplashScreen" because we were firing all of the events in the one sub routine. When we broke the events out into a Select Case statement, and drove it with a dispatchertimer, the textbox updated nicely. So, it turns out that MojoFilter is correct! Thanks!
MBunds