views:

39

answers:

3

Hi !

I'm working on a WinForms solution in VB.NET. It's been a while since I'm mostly a web developper. So what I need to do is to replicate the behavior of Microsoft Office product for the Cut, Copy, Paste and Undo menus and toolbar. Which meens, I need to enable Cut and Copy when and only when there's some selected text on the Form. The Paste menu have to be enabled only when the is some text in the clipboard.

Do you have any ideay about how to accomplish that ? I probably would have to check some event in the TextBox's to check if some text is selected (MouseUp ?). Then in the Enter event, I would check if there's something in the Clipboard to enabled Paste menu...

If you have any suggestions, samples, etc. I would really appreciate it !

Thanks a lot !

+1  A: 

That should all be default behavior if you're using the standard WinForms controls. You don't need to implement that yourself unless you have a custom context menu.

Jacob Ewald
You have to implement commanding in the app on a global scale to get the enable/disable of the button on a toolbar for say copy. It does not magically happen.
Aaron
Thanks Aaron ! But someone somwhere already did that, I'm pretty sure. That's why I'm asking for some thoughts and guidelines, maybe even source code samples. Just to get me started on the right track.
ultraman69
Thanks for your answer Jacob, but if it's standard in WinForms controls, it's just not working here.
ultraman69
A: 

First off if you are not tied to WinForms, switch to WPF as this is much easier to accomplish since commanding is built in and a much more friendlier technology IMHO.

For cutting and copying you can make use of the Cut/Copy/Paste methods respectively, these exist on the TextBoxBase class, since the .NET 3.

The more difficult piece of your puzzle is dealing with the commands on a global scale, via your toolbar. You will need to implement the command pattern to make this possible.

Aaron
Thaks again Aaron ! I'm tied to WinForms unfortunately. But I'll look at your suggestion to implement command pattern, wich seems a good idea for my case.
ultraman69
+1  A: 

The Application.Idle event is good to do this, it runs after the last input event is retrieved. You just need to check if the currently active control is capable of copy/paste. Make your form's code look similar to this, using a ToolStrip with the 3 buttons:

Public Class Form1
    Public Sub New()
        InitializeComponent()
        AddHandler Application.Idle, AddressOf UpdateButtons
    End Sub

    Protected Overrides Sub OnFormClosing(ByVal e As System.Windows.Forms.FormClosingEventArgs)
        RemoveHandler Application.Idle, AddressOf UpdateButtons
        MyBase.OnFormClosing(e)
    End Sub

    Private Sub UpdateButtons(ByVal sender As Object, ByVal e As EventArgs)
        Dim box = TryCast(Me.ActiveControl, TextBoxBase)
        CopyButton.Enabled = box IsNot Nothing And box.SelectionLength > 0
        CutButton.Enabled = CopyButton.Enabled
        PasteButon.Enabled = box isnot Nothing and Clipboard.ContainsText
    End Sub

    Private Sub CopyButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyButton.Click
        Dim box = TryCast(Me.ActiveControl, TextBoxBase)
        If box isnot Nothing then box.Copy()
    End Sub

    '' etc...


End Class
Hans Passant
Hans, thank you very much for this ! That is exactly what I was looking for : a fast and efficient way to do this. You just made my day.
ultraman69
@ultraman69 This is the exact same thing you will do when you make use of the command pattern in reference to the Application.Idle. However when the event comes through, you would then make use of the command pattern, unless your application is not going to grow...then placing it all in a single file will suffice.
Aaron
Absolutely Aaron, but I was realy missing the particular Application.Idle event which is the starting point. Thanks everyone for your help !
ultraman69