|
I mentioned in another post that I now work for Microsoft. Because of this, I'm moving my blog to the MSDN blog site. You can find my new blog here:
http://blogs.msdn.com/jerrydixon
This site is where you'll find all of my newest posts. Stop by when you get a chance.
My thanks go out to the people at SysCon. They've provided a great hosting site over the past few years.
Back in 2004, I blogged about CAPICOM and how it can be used to obtain a reference to a site's SSL Certificate. (See this post.) Well, now that Vista is out, it seems that CAPICOM is going away. Here is an excerpt from the CAPICOM reference on MSDN:
Beginning with Windows Vista, CAPICOM is no longer supported. On these platforms, you should use the Certificate Enrollment API or the .NET Framework to implement security features.
Those of you that are moving to Vista should check this out. You ARE moving to Vista, aren't you? ![]()
I've accepted a really cool position at Microsoft. I'll be helping people work with all kinds of technologies, both current and new. (If you know me, then you know that I LOVE new technology.) Anyway, this means that a few things will be changing:
Well, that's my news. I'm really excited about my new job, but things will be hectic for a while. Don't be surprised if I'm out of pocket for a while.
Merging menus in an MDI application is easy. You simply set a couple of properties and it happens. This does not work with toolstrips, however. You have to write some code. I couldn't find much on the web about this, so here is my solution.
First, you need to create a toolstrip on the main form. In a fit of originality, I called mine "tsMain". Set the "AllowMerge" property of this toolstrip to True. Now create a toolstrip in a child form. I'll call this one "tsChild". Set the "AllowMerge" property of this toolstrip to True also. Go to each item in this toolstrip, and set the "MergeAction" and "MergeIndex" properties as you see fit. I used Append for "MergeAction" because I want the ToolStripButtons to be added to the right on my main toolstrip.
If we were working with menus, then we would be finished. However, because we are working with toolstrips, we have to write some code.
Each MDI Child needs a public property that exposes its toolstrip:
Public ReadOnly Property MainToolStrip() As ToolStrip
Get
Return tsChild
End Get
End Property
Next, the main form needs this code:
Private Sub MainForm_MdiChildActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MdiChildActivate
' remove any previously-merged toolstrips
ToolStripManager.RevertMerge(tsMain)
' get child toolstrip
Dim ChildToolStrip As ToolStrip = Nothing
If Me.ActiveMdiChild IsNot Nothing Then
If Me.ActiveMdiChild.Name = "MDIChildForm1" Then
Dim f As MDIChildForm1 = DirectCast(ActiveMdiChild, MDIChildForm1)
ChildToolStrip = f.MainToolStrip
ElseIf Me.ActiveMdiChild.Name = "MDIChildForm2" Then
Dim f As MDIChildForm2 = DirectCast(ActiveMdiChild, MDIChildForm2)
ChildToolStrip = f.MainToolStrip
End If
End If
' merge it, if present
If ChildToolStrip IsNot Nothing Then
ToolStripManager.Merge(ChildToolStrip, tsMain)
End If
End Sub
This works great for me. I hope it helps you too.
UPDATE: Colin Neller pointed out that I should have used an interface in the above code. He is absolutely correct. Here is the corrected code:
Interface:
Public Interface IToolStripForm
ReadOnly Property MainToolStrip() As ToolStrip
End Interface
Event:
Private Sub MainForm_MdiChildActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MdiChildActivate
' remove any previously-merged toolstrips
ToolStripManager.RevertMerge(tsMain)
' get child toolstrip
Dim ChildToolStrip As ToolStrip = Nothing
Dim ToolStripForm As IToolStripForm = Nothing
If Me.ActiveMdiChild IsNot Nothing Then
ToolStripForm = TryCast(Me.ActiveMdiChild, IToolStripForm)
If ToolStripForm IsNot Nothing Then
ChildToolStrip = ToolStripForm.MainToolStrip
End If
End If
' merge it, if present
If ChildToolStrip IsNot Nothing Then
ToolStripManager.Merge(ChildToolStrip, tsMain)
End If
End Sub
Over the past 7 years, I've considered myself a Web Developer. Oh, I've kept my hand in the Windows application world, creating the odd Windows app here and there. However, at least 75% of all of my line-of-business applications were Web applications. In some cases, this was because I actually created Web apps. You know, Internet-accessible apps. In other cases, however, I created Intranet apps. These apps were intended to be used solely by internal employees, with no possibility of external access.
Why did I do this? I'm sure that you know the answer. It's because of the deployment nightmare associated with Windows apps. Installing my app on 400+ desktops was a real pain, no matter what deployment tool we used. Maintaining that installed base was a pain too. So, years and years ago, I started creating web apps for internal employees.
This worked fairly well, but you know how users are. They wanted my web apps to have the same complicated UI that they were used to with their other, Windows, apps. They wanted instantaneous response to button-clicks. They wanted buttons that changed that value over there, and drop-downs that changed that drop-down over there. In short, they wanted near-instantaneous, client-side interactions via very rich and responsive GUIs. Well, this can be done, but it's not easy, even with AJAX. So, I decided to try ClickOnce.
ClickOnce is a new deployment feature in Visual Studio 2005. It allows you to easily deploy Windows applications via the Web. I can't say enough about this feature. It rocks. You can read about it here.
Now, after a number of demos and trials, my company has decided to abandon Web apps for internal-only use. We now use ClickOnce-deployed Windows apps. We still use Web Services and such for our middle and back-end tiers, but the UI is strictly Windows. I've been able to create richer, more responsive UIs, and I've done it more quickly than I could have using Web apps.
If you find youself in my situation, I strongly suggest that you give it a try.

