Reload item on main form after closing settings dialog
-
Friday, March 05, 2010 1:16 AMIs 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.
Answers
-
Friday, March 05, 2010 6:09 AMModerator
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/- Proposed As Answer by Sam WoodMVP, Moderator Sunday, March 14, 2010 8:59 AM
- Marked As Answer by Sam WoodMVP, Moderator Wednesday, March 24, 2010 4:41 AM
All Replies
-
Friday, March 05, 2010 1:39 AM
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 6:09 AMModerator
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/- Proposed As Answer by Sam WoodMVP, Moderator Sunday, March 14, 2010 8:59 AM
- Marked As Answer by Sam WoodMVP, Moderator Wednesday, March 24, 2010 4:41 AM
-
Friday, March 05, 2010 6:54 PMThanks 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 11:38 PMModerator
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/ -
Saturday, March 06, 2010 1:21 AM
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 4:34 AMModerator
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 9:12 PM
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:34 PMModeratorWhat'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:57 PMModerator
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/ -
Sunday, March 07, 2010 2:41 AMThank 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:51 AMModerator
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 1:50 PM
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 6:26 PMModerator
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/ -
Wednesday, March 10, 2010 12:55 AM
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 4:59 AMModeratorSweet! So does it work? :)
Tentacle Blog: http://www.tentaclesoftware.com/blog/
WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/ -
Wednesday, March 10, 2010 7:29 PMHi 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. -
Thursday, March 11, 2010 6:11 AMModerator
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 11:37 AMNothing 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 4:55 PMYou should define your functions outside of other functions.
-- -
Thursday, March 11, 2010 6:33 PMSorry, Typo - Corrected now.
-
Thursday, March 11, 2010 9:09 PMModeratorCan 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/ -
Friday, March 12, 2010 12:25 AMHi 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 8:06 AMModerator
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 10:08 AMHi 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. -
Saturday, May 08, 2010 10:15 PM
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 ClassI 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:36 PMModerator
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 ClassThat'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 11:30 PM
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.
-
Monday, May 10, 2010 12:19 AMModeratorI 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 4:50 PM
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 6:26 PMModerator
Yeah, I like Andreas' solution quite a lot.
Tentacle Blog: http://www.tentaclesoftware.com/blog/
WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/