none
Reload item on main form after closing settings dialog

    Question

  • Is it possible to reload say a text box on the main window after the settings form is closed? I've tried using focus events but this doesn't seem to work.
    Thanks.
    Friday, March 05, 2010 1:16 AM

Answers

All replies

  • I tried to call the parents load event when the child (settings) closes, but this doesnt seem to work either:

        Private Sub SettingsTabUserControl_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            MainTabUserControl.Load(Nothing, Nothing)
        End Sub
    Friday, March 05, 2010 1:39 AM
  • You've got a few options, none of which are terribly clean.

    1) Build your own message bus
    2) Send a health notification (set to Info so that it doesn't show up in the Console) from the Settings tab with an identifier that the Console Tab is expecting
    3) Write to a file on the disk that the Console Tab has a FileSystemWatcher on

    I used #2 in Disk Management.
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Friday, March 05, 2010 6:09 AM
    Moderator
  • Thanks Sam, I guess method 2 would be best for me.

    I've put this in my HomeServerSettingsExtender.vb:

        Public Function Commit() As Boolean Implements ISettingsTab.Commit
            Dim pInfo As New WHSInfoClass()
            pInfo.AddNotification("5976a84b-92c0-43bb-b432-a519d120663a", WHS_Notification_Severity.WHS_ERROR, "My Plug-in", "Tab Closed", "", "", "")
            Return True
        End Function


    This seems to add a notifcation for a second - How do I watch for this on the main form (MainTabUserControl.vb)?

    I've got the following under New()

            Dim pInfo As New WHSInfoClass()
            pInfo.Init("MyWHSApp")
            pInfo.RegisterForNotifications()
            ' Refresh code here
    Friday, March 05, 2010 6:54 PM
  • You want to use WHS_INFO, not WHS_ERROR - WHS_INFO doesn't show up in the Console as a health notification, but it still gets put on the queue for anyone that's registered for notifications.

    You're also only seeing the notification for an instant because WHS will remove any notifications tied to an instance of WHSInfoClass that doesn't exist anymore. Because you're instantiating a new WHSInfoClass in that method, it gets disposed when the method returns, and your notification gets cleaned up.

    So, I'd have a private instance of WHSInfoClass inside HomeServerSettingsExtender, like:

    private readonly WHSInfoClass interop = new WHSInfoClass();

     

     


    Then you can reference that instance in your Commit() method. The other issue is you'll need to remove the notification in order to fire it again the next time you want to Commit(). I do that like this:

            public bool Commit()
            {
    
                if (settingsTabControl.IsApplyPending)
                {
                    if (IsNotificationAdded)
                    {
                        //Remove 'Settings Saved' Notification if present
                        try
                        {
                            interop.RemoveNotification("WHSDiskManagement.SettingsTab.Settings.Saved");
                            IsNotificationAdded = false;
                        }
                        catch (Exception error)
                        {
                            Log.TraceMessage(TraceLevel.Error, Component.SettingsTab, string.Format("Unable to RemoveNotification. {0}", error.Message));
                        }
                    }
                    //Save settings
                    Serialize<ConsoleTabSettings>.ToXml(settingsTabControl.AppSettings, string.Format(@"{0}\{1}", ApplicationFolders.AppFolder(interop).Path, Resources.XMLFileAppSettings));
                    Serialize<ServerWireframe>.ToXml(settingsTabControl.ServerWireframe, string.Format(@"{0}\{1}", ApplicationFolders.AppFolder(interop).Path, Resources.XMLServerWireframe));
    
                    //Send 'Settings Saved' Notification
                    Log.TraceMessage(TraceLevel.Info, Component.Settings, "Settings committed.");
                    interop.AddNotification("WHSDiskManagement.SettingsTab.Settings.Saved", WHS_Notification_Severity.WHS_INFO, "WHS Disk Management Settings", "Settings have been saved. Refresh GUI.", null, null, null);
                    IsNotificationAdded = true;
    
                    settingsTabControl.IsApplyPending = false;
                }
                
                return false;
            }



    IsNotificationAdded is just a bool I can keep a reference to inside HomeServerSettingsExtender. I use a try/catch before removing, because WHS throws an exception if you try to remove a notification that doesn't exist.

    In my MainTabUserControl, the NotificationCallback looks like this:

            public void NotificationChanged(string UniqueID, WHS_Notification_Type Type, WHS_Notification_Severity Severity, int IsSuppressed, string textHeader, string textDescription, string helpFilename, string helpSection, string helpLinkText)
            {
                if ((UniqueID == "WHSDiskManagement.SettingsTab.Settings.Saved") && (Type == WHS_Notification_Type.WHS_NOTIFICATION_ADD))
                {
                    Log.TraceMessage(TraceLevel.Info, Component.NotificationCallback, string.Format("{0} {1}", textHeader, textDescription));
    
                    if (RefreshDelegate != null)
                    {
                        RefreshDelegate();
                    }
                }
            }

    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Friday, March 05, 2010 11:38 PM
    Moderator
  • I'm using WHS_ERROR for testing only, good visual feedback.
    Do I not need to register for notifications with INotificationCallback?


    HomeServerSettingsExtender:

    Public Class HomeServerSettingsExtender
        Implements ISettingsTab ...etc....
    
        Private ReadOnly interop As WHSInfoClass = New WHSInfoClass()
    
        Public Function Commit() As Boolean Implements ISettingsTab.Commit
            interop.AddNotification("5976a84b-92c0-43bb-b432-a519d120663a", WHS_Notification_Severity.WHS_ERROR, "My Plug-in", "Tab Closed", "", "", "")
            ' interop.RemoveNotification("5976a84b-92c0-43bb-b432-a519d120663a")
    
            Return True
        End Function
    


    MainTabUserControl:
        Public Sub NotificationChanged(ByVal UniqueID As String, ByVal Type As WHS_Notification_Type, ByVal Severity As WHS_Notification_Severity, ByVal IsSuppressed As Integer, ByVal textHeader As String, ByVal textDescription As String, ByVal helpFilename As String, ByVal helpSection As String, ByVal helpLinkText As String)
            If UniqueID = "5976a84b-92c0-43bb-b432-a519d120663a" Then
                MessageBox.Show("Worked!")
            End If
            MessageBox.Show("Nope...")
        End Sub
    Saturday, March 06, 2010 1:21 AM
  • Yeah, you need to register for notifications and provide a callback for WHS to send messages to.

    Inside the MainTabUserControl:

            public WHSInfoClass Interop;
            private NotificationCallback callback;

    Then OnLoad() (or wherever):
                callback = new NotificationCallback(RefreshSettings);
                Interop.RegisterForNotifications(callback);

    My NotificationCallback object:
        public class NotificationCallback : INotificationCallback
        {
            private readonly MainTabUserControl.RefreshSettingsDelegate RefreshDelegate;
    
            public NotificationCallback(MainTabUserControl.RefreshSettingsDelegate RefreshDelegate)
            {
                this.RefreshDelegate = RefreshDelegate;
            }
    
            public void BackupStateChanged(WHSBackupState State)
            {
            }
    
            public void Disconnected()
            {
            }
    
            public void NotificationChanged(string UniqueID, WHS_Notification_Type Type, WHS_Notification_Severity Severity, int IsSuppressed, string textHeader, string textDescription, string helpFilename, string helpSection, string helpLinkText)
            {
                if ((UniqueID == "WHSDiskManagement.SettingsTab.Settings.Saved") && (Type == WHS_Notification_Type.WHS_NOTIFICATION_ADD))
                {
                    Log.TraceMessage(TraceLevel.Info, Component.NotificationCallback, string.Format("{0} {1}", textHeader, textDescription));
    
                    if (RefreshDelegate != null)
                    {
                        RefreshDelegate();
                    }
                }
            }
    
            public void PhysicalDiskChanged(IDiskInfo changedIDiskInfo)
            {
            }
    
            public void ReConnected()
            {
            }
    
            public void UserInfoChanged()
            {
            }
        }

    I'm using a delegate to refresh the settings in my MainConsoleTab. You can skip that if your MainTabUserControl inherits INotificationCallback directly, and you just implement those methods in the control itself. So your MainTabUserControl might look like:
    public partial class MainTabUserControl : UserControl, INotificationCallback

    And then it could pass itself ("this") to the RegisterForNotifications method.

    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Saturday, March 06, 2010 4:34 AM
    Moderator
  • Thanks Sam, I'm mostly there, I'm having some issues with the Notification callback class though.
    I've implemented the required subs in the class but it's still erroring, probably from my converting to vb.

    I've also uploaded the project: http://drop.io/madlanwhs#

    NotificationCallback object:
    Public Class NotificationCallback
        Implements INotificationCallback
    
        Public Sub BackupStateChanged(ByVal State As WHSBackupState)
        End Sub
    
        Public Sub Disconnected()
        End Sub
    
        Public Sub NotificationChanged(ByVal UniqueID As String, ByVal Type As WHS_Notification_Type, ByVal Severity As WHS_Notification_Severity, ByVal IsSuppressed As Integer, ByVal textHeader As String, ByVal textDescription As String, ByVal helpFilename As String, ByVal helpSection As String, ByVal helpLinkText As String)
            If (UniqueID = "5976a84b-92c0-43bb-b432-a519d120663a") Then
                RefreshSettings()
            End If
        End Sub
    
        Private Sub RefreshSettings()
            MessageBox.Show("Refresh code here")
        End Sub
    
        Public Sub PhysicalDiskChanged(ByVal changedIDiskInfo As IDiskInfo)
        End Sub
    
        Public Sub ReConnected()
        End Sub
    
        Public Sub UserInfoChanged()
        End Sub
    End Class
    
    

    MainTabUserControl:

    Public Class MainTabUserControl
    
        Dim pInfo As New WHSInfoClass()
        Dim m_consoleServices As IConsoleServices
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
    
        End Sub
    
        Public Sub New(ByVal width As Integer, ByVal height As Integer, ByVal consoleServices As IConsoleServices)
            Me.New()
    
            Me.Width = width
            Me.Height = height
            Me.m_consoleServices = consoleServices
        End Sub
    
        Private Sub MainTabUserControl_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            pInfo = New NotificationCallback()
            pInfo.RegisterForNotifications(NotificationCallback)
        End Sub
    
    
    End Class
    Saturday, March 06, 2010 9:12 PM
  • What's the error you're getting?
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Saturday, March 06, 2010 9:34 PM
    Moderator
  • OK, so there are some compilation errors up front. Try changing to this:

    Public Class MainTabUserControl
    
        Dim pInfo As New WHSInfoClass()
        ' Create a new instance of your NotificationCallback class
        Dim nCallback As New NotificationCallback()
        Dim m_consoleServices As IConsoleServices
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
    
        End Sub
    
        Public Sub New(ByVal width As Integer, ByVal height As Integer, ByVal consoleServices As IConsoleServices)
            Me.New()
    
            Me.Width = width
            Me.Height = height
            Me.m_consoleServices = consoleServices
        End Sub
    
        Private Sub MainTabUserControl_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ' pInfo isn't a NotificationCallback, it's already defined as a WHSInfoClass (which you've already instantiated)
            ' pInfo = New NotificationCallback()
            pInfo.RegisterForNotifications(nCallback)
        End Sub
    
    
    End Class

    Then you need to implement the INotificationCallback interface correctly:

    Public Class NotificationCallback
        Implements INotificationCallback
    
        Public Sub PhysicalDiskChanged(ByVal pDiskInfo As IDiskInfo) Implements INotificationCallback.PhysicalDiskChanged
        End Sub
    
        Public Sub BackupStateChanged(ByVal State As WHSBackupState) Implements INotificationCallback.BackupStateChanged
        End Sub
    
        Public Sub UserInfoChanged() Implements INotificationCallback.UserInfoChanged
        End Sub
    
        Public Sub Disconnected() Implements INotificationCallback.Disconnected
        End Sub
    
        Public Sub ReConnected() Implements INotificationCallback.ReConnected
        End Sub
    
        Private Sub RefreshSettings()
            MessageBox.Show("Refresh code here")
        End Sub
    
        Public Sub NotificationChanged(ByVal UniqueID As String, ByVal Type As WHS_Notification_Type, ByVal Severity As WHS_Notification_Severity, ByVal IsSuppressed As Integer, ByVal textHeader As String, ByVal textDescription As String, ByVal helpFilename As String, ByVal helpSection As String, ByVal helpLinkText As String) Implements INotificationCallback.NotificationChanged
            If (UniqueID = "5976a84b-92c0-43bb-b432-a519d120663a") Then
                RefreshSettings()
            End If
        End Sub
    End Class

    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Saturday, March 06, 2010 9:57 PM
    Moderator
  • Thank you for your help Sam, it's working a treat now.
    One last question - I'm calling (In Notification Changed) a sub from my MainTabUserControl with:

        Dim MainTab As MainTabUserControl    ' (In NotificationCallback class)


                Me.MainTab.ReloadBrowser()

    But this is not working - no error or obvious reason why?
    If I create a new instance of MainTabUserControl it causes the console to lockup.

    I cannot set the ReloadBrowser sub as shared because it's using several other non shared subs.

    Thanks.
    • Edited by madlan Sunday, March 07, 2010 2:51 AM
    Sunday, March 07, 2010 2:41 AM
  • Couple of ways to approach that. One is using a delegate (where you pass through a reference to the ReloadBrowser() method in NotificationCallback's constructor), or you could just pass through a reference to the whole MainTabUserControl.

    Here's mine again. Note the RefreshDelegate reference in the constructor at the top, and the private field that holds the reference.

        public class NotificationCallback : INotificationCallback
        {
            private readonly MainTabUserControl.RefreshSettingsDelegate RefreshDelegate;
    
            public NotificationCallback(MainTabUserControl.RefreshSettingsDelegate RefreshDelegate)
            {
                this.RefreshDelegate = RefreshDelegate;
            }
    
            public void BackupStateChanged(WHSBackupState State)
            {
            }
    
            public void Disconnected()
            {
            }
    
            public void NotificationChanged(string UniqueID, WHS_Notification_Type Type, WHS_Notification_Severity Severity, int IsSuppressed, string textHeader, string textDescription, string helpFilename, string helpSection, string helpLinkText)
            {
                if ((UniqueID == "WHSDiskManagement.SettingsTab.Settings.Saved") && (Type == WHS_Notification_Type.WHS_NOTIFICATION_ADD))
                {
                    Log.TraceMessage(TraceLevel.Info, Component.NotificationCallback, string.Format("{0} {1}", textHeader, textDescription));
    
                    if (RefreshDelegate != null)
                    {
                        RefreshDelegate();
                    }
                }
            }
    
            public void PhysicalDiskChanged(IDiskInfo changedIDiskInfo)
            {
            }
    
            public void ReConnected()
            {
            }
    
            public void UserInfoChanged()
            {
            }
        }

    Because we don't need any parameters, the delegate signature is easy. Inside MainTabUserControl:

    public delegate void RefreshSettingsDelegate();
    
    private void RefreshSettings()
    {
             // Refresh stuff here
    }
    
    private void MainTabUserControl_Load(object sender, EventArgs e)
    {
             //other stuff here
             callback = new NotificationCallback(RefreshSettings);
             // now register for notifications using a reference to callback
    }
    So you're passing a reference to your RefreshSettings() method to NotificationCallback in its constructor.
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Sunday, March 07, 2010 2:51 AM
    Moderator
  • Does NotificationCallback require another value?
    I'm getting 'Expression does not produce a value' on refreshsettings for both 'Dim nCallback As New NotificationCallback(refreshsettings)' and
    nCallback = New NotificationCallback(RefreshSettings)

    Public Class MainTabUserControl
    
        Dim pInfo As New WHSInfoClass()
        ' Create a new instance of your NotificationCallback class
        Dim nCallback As New NotificationCallback(RefreshSettings)
        Dim m_consoleServices As IConsoleServices
        Dim SettingsTab As New SettingsTabUserControl
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
            ' Add any initialization after the InitializeComponent() call.
    
        End Sub
    
        Public Sub New(ByVal width As Integer, ByVal height As Integer, ByVal consoleServices As IConsoleServices)
            Me.New()
    
            Me.Width = width
            Me.Height = height
            Me.m_consoleServices = consoleServices
        End Sub
    
        Private Sub MainTabUserControl_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            nCallback = New NotificationCallback(RefreshSettings)
            pInfo.RegisterForNotifications(nCallback)
        End Sub
    
        Public Delegate Sub RefreshSettingsDelegate()
    
        Private Sub RefreshSettings()
            MessageBox.Show("Refreshed")
        End Sub
    
    End Class


    Public Class NotificationCallback
        Implements INotificationCallback
        ' Dim MainTab As New MainTabUserControl()
        Private ReadOnly RefreshDelegate As MainTabUserControl.RefreshSettingsDelegate
    
        Public Sub New(ByVal RefreshDelegate As MainTabUserControl.RefreshSettingsDelegate)
            Me.RefreshDelegate = RefreshDelegate
        End Sub
        Public Sub PhysicalDiskChanged(ByVal pDiskInfo As IDiskInfo) Implements INotificationCallback.PhysicalDiskChanged
        End Sub
    
        Public Sub BackupStateChanged(ByVal State As WHSBackupState) Implements INotificationCallback.BackupStateChanged
        End Sub
    
        Public Sub UserInfoChanged() Implements INotificationCallback.UserInfoChanged
        End Sub
    
        Public Sub Disconnected() Implements INotificationCallback.Disconnected
        End Sub
    
        Public Sub ReConnected() Implements INotificationCallback.ReConnected
        End Sub
    
        Private Sub RefreshSettings()
            MessageBox.Show("Refresh code here")
        End Sub
    
        Public Sub NotificationChanged(ByVal UniqueID As String, ByVal Type As WHS_Notification_Type, ByVal Severity As WHS_Notification_Severity, ByVal IsSuppressed As Integer, ByVal textHeader As String, ByVal textDescription As String, ByVal helpFilename As String, ByVal helpSection As String, ByVal helpLinkText As String) Implements INotificationCallback.NotificationChanged
            If ((UniqueID = "5976a84b-92c0-43bb-b432-a519d120663a") And (Type = WHS_Notification_Type.WHS_NOTIFICATION_ADD)) Then
                RefreshSettings()
            End If
        End Sub
    End Class
    Sunday, March 07, 2010 1:50 PM
  • Looks like my VB.NET-fu isn't as good as I thought ;) Delegates are instantiated differently, try this:

    Dim nCallback As New NotificationCallback(New RefreshSettingsDelegate(AddressOf RefreshSettings))

    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Sunday, March 07, 2010 6:26 PM
    Moderator
  • Hi  Sam, I think I'm finally there!:

    Imports Microsoft.HomeServer.SDK.Interop.v1
    
    Public Class MainTabUserControl
    
        Dim pInfo As New WHSInfoClass()
        Dim nCallback As New NotificationCallback(New RefreshSettingsDelegate(AddressOf RefreshSettings))
    
        Dim m_consoleServices As IConsoleServices
        Dim SettingsTab As New SettingsTabUserControl
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
            ' Add any initialization after the InitializeComponent() call.
    
        End Sub
    
        Public Sub New(ByVal width As Integer, ByVal height As Integer, ByVal consoleServices As IConsoleServices)
            Me.New()
    
            Me.Width = width
            Me.Height = height
            Me.m_consoleServices = consoleServices
        End Sub
    
        Private Sub MainTabUserControl_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            nCallback = New NotificationCallback(AddressOf RefreshSettings)
            pInfo.RegisterForNotifications(nCallback)
        End Sub
    
        Public Delegate Sub RefreshSettingsDelegate()
    
        Private Sub RefreshSettings()
            MessageBox.Show("Refreshed")
        End Sub
    
    End Class
    
    
    Public Class NotificationCallback
        Implements INotificationCallback
    
        Private ReadOnly RefreshDelegate As MainTabUserControl.RefreshSettingsDelegate
    
        Public Sub New(ByVal RefreshDelegate As MainTabUserControl.RefreshSettingsDelegate)
            Me.RefreshDelegate = RefreshDelegate
        End Sub
        Public Sub PhysicalDiskChanged(ByVal pDiskInfo As IDiskInfo) Implements INotificationCallback.PhysicalDiskChanged
        End Sub
    
        Public Sub BackupStateChanged(ByVal State As WHSBackupState) Implements INotificationCallback.BackupStateChanged
        End Sub
    
        Public Sub UserInfoChanged() Implements INotificationCallback.UserInfoChanged
        End Sub
    
        Public Sub Disconnected() Implements INotificationCallback.Disconnected
        End Sub
    
        Public Sub ReConnected() Implements INotificationCallback.ReConnected
        End Sub
    
        Private Sub RefreshSettings()
            RefreshDelegate.Invoke()
        End Sub
    
        Public Sub NotificationChanged(ByVal UniqueID As String, ByVal Type As WHS_Notification_Type, ByVal Severity As WHS_Notification_Severity, ByVal IsSuppressed As Integer, ByVal textHeader As String, ByVal textDescription As String, ByVal helpFilename As String, ByVal helpSection As String, ByVal helpLinkText As String) Implements INotificationCallback.NotificationChanged
            If ((UniqueID = "5976a84b-92c0-43bb-b432-a519d120663a") And (Type = WHS_Notification_Type.WHS_NOTIFICATION_ADD)) Then
                RefreshSettings()
            End If
        End Sub
    End Class
    

    Wednesday, March 10, 2010 12:55 AM
  • Sweet! So does it work? :)
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Wednesday, March 10, 2010 4:59 AM
    Moderator
  • Hi Sam, works great!

    One thing though - If I call another sub from within the RefreshSettings() sub it doesn't work?
    Can the delegated Sub not access subs outside of itself?

    Thanks.
    Wednesday, March 10, 2010 7:29 PM
  • It should be able to, yes. Are you getting an error?


    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Thursday, March 11, 2010 6:11 AM
    Moderator
  • Nothing happens - If I put a MessageBox in Private Sub RefreshSettings() it works fine, If I then call another sub, say, ReloadBrowser() (Which just has a MessageBox stating the name of the sub) from within RefreshSettings() Nothing - No compilation or runtime errors?



    Public Delegate Sub RefreshSettingsDelegate()

    Private Sub RefreshSettings()
    MessageBox.Show("This Works")
    ReloadBrowser()
    End Sub

    Private Sub ReloadBrowser()
    MessageBox.Show("This Doesn't")
    End Sub
    • Edited by madlan Thursday, March 11, 2010 6:30 PM Typo
    Thursday, March 11, 2010 11:37 AM
  • You should define your functions outside of other functions.
    --
    Thursday, March 11, 2010 4:55 PM
  • Sorry, Typo - Corrected now.
    Thursday, March 11, 2010 6:33 PM
  • Can you zip and post your solution for me to have a look at again? Better to see how you've got things set up in context.
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Thursday, March 11, 2010 9:09 PM
    Moderator
  • Hi Sam, I've been playing around this evening and I think its actually the browser object I'm using (GeckoFX)
    If I use WebBrowser.Navigate("www.microsoft.com") via a button on the toolbar it loads - If I do this via the delegate nothing happens.

    I've uploaded a zip with the solution (plus Gecko requirements)
    http://drop.io/madlanwhs/asset/home-server-add-in1-zip-2

    Thetwo requirements for the browser object:

    Skybound.Gecko.dll
    xulrunner

    Need to be in WHS Console root.

    Thanks.
    Friday, March 12, 2010 12:25 AM
  • ReloadBrowser() is definitely getting called - if I stick a MessageBox.Show() in there it fires as expected.

    You're not attempting to remove your notification before you send it, though. A notification with a specific UniqueId can't be added more than once, and your MainTab is responding to WHS_NOTIFICATION_ADD. So you need to be attempting a remove of that notification before sending it (see my example further up - it needs to be wrapped in a try/catch block).

    I can't help you with the browser object issue; I've never used this one before. I also have to ask why you're trying to load a web browser in the WHS Console - if you're just trying to show the user a URL, there are ways to open a browser on the local client machine by clicking a link in the Console session.


    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/

    Friday, March 12, 2010 8:06 AM
    Moderator
  • Hi Sam,

    Ahh, missed that - will wrap it as your example.
    The application is browser based (runs as a service on the WHS with no front end - all web based), I'm using the settingstab to setup the web host app and a browser.

    Thanks.
    Friday, March 12, 2010 10:08 AM
  • Hi Sam,

    I've been looking at Andrea's singleton solution as a possible work around to the issues I was\am having refreshing the browser object.

    However, I'm having difficulty converthing his class example to VB.net
    I've sucessfully implemented it in C# which seems to work well.

    I'm creating a new class with ChangeNotifier:

     

    public sealed class ChangeNotifier {
      public event EventHandler Changed;
    
      private ChangeNotifier() {
      }
      public static readonly ChangeNotifier Instance = new ChangeNotifier();
    
      public void Notify() {
        OnChanged(new EventArgs());
      }
    
      void OnChanged(EventArgs e) {
        EventHandler handler = Changed;
        // Make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        if (handler != null) {
          handler(this, e);
        }
      }
    }

     

     

     

    Converted to VB:

    Public NotInheritable Class ChangeNotifier
      Public Event Changed As EventHandler
      
      Private Sub New()
      End Sub
      Public Shared ReadOnly Instance As New ChangeNotifier()
      
      Public Sub Notify()
        OnChanged(New EventArgs())
      End Sub
      
      Private Sub OnChanged(ByVal e As EventArgs)
        Dim handler As EventHandler = Changed
        ' Make a temporary copy of the event to avoid possibility of
        ' a race condition if the last subscriber unsubscribes
        ' immediately after the null check and before the event is raised.
        RaiseEvent handler(Me, e)
      End Sub
    End Class
    
    
    
    

    I think the problem is with the event handler method?
    I've uploaded two projects, one is the working C# implementation, the other is the VB version I'm having problems with: http://drop.io/fboslqg

     

     

     

    Saturday, May 08, 2010 10:15 PM
  • Public NotInheritable Class ChangeNotifier
      Public Event Changed As EventHandler
      
      Private Sub New()
      End Sub
      Public Shared ReadOnly Instance As New ChangeNotifier()
      
      Public Sub Notify()
        OnChanged(New EventArgs())
      End Sub
      
      Private Sub OnChanged(ByVal e As EventArgs)
        Dim handler As EventHandler = Changed
        ' Make a temporary copy of the event to avoid possibility of
        ' a race condition if the last subscriber unsubscribes
        ' immediately after the null check and before the event is raised.
        RaiseEvent handler(Me, e)
      End Sub
    End Class
    That's what I get if I run the C# class through a C#-to-VB.NET converter. It looks identical to what you've got already - what's the issue that you're experiencing?
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Saturday, May 08, 2010 10:36 PM
    Moderator
  • I get the following errors on:

    RaiseEvent handler (Me, e)

    'handler' is not an event of 'Microsoft.HomeServer.HomeServerConsoleTab.SingletonTestVB.ChangeNotifier'.


    Dim handler As EventHandler = Changed
    'Public Event Changed(sender As Object, e As System.EventArgs)' is an event, and cannot be called directly. Use a 'RaiseEvent' statement to raise an event.

    Saturday, May 08, 2010 11:30 PM
  • I don't know enough about VB.NET to give you pointers there, unfortunately. Maybe hit the VB.NET forums.
    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Monday, May 10, 2010 12:19 AM
    Moderator
  • Hi Sam,

    This is from a VB forum I asked for advice:

    "VB.Net's Event handling / raising syntax is slightly different from C#'s syntax and the issue the C# code is attempting to avoid (a race condition) isn't a concern in VB so you can just raise the event directly.

    Changed the OnChanged event to:

    Private Sub OnChanged(ByVal e As EventArgs)
      RaiseEvent Changed(Me, e)
    End Sub
    "

    I've tested this and it works great, much better than the alternatives.

    Monday, May 10, 2010 4:50 PM
  • Yeah, I like Andreas' solution quite a lot.


    Tentacle Blog: http://www.tentaclesoftware.com/blog/
    WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/
    Monday, May 10, 2010 6:26 PM
    Moderator