Índice de la sección dedicada a .NET (en el Guille) Utilidades

Un formulario para Buscar/Reemplazar

Código para Visual Basic.NET (VB.NET)

Código para C Sharp (C#)



Publicado el 01/Nov/2004
Actualizado el 01/Nov/2004
Autor: Guillermo 'guille' Som


Aquí te muestro una clase que servirá para tener el "típico" formulario de buscar y reemplazar.

 

Esta "utilidad" está formada por varias clases, principalmente un formulario que será el que se mostrará al usuario con las opciones típicas para realizar búsquedas y reemplazos. Además del formulario tenemos también la clase principal a usar, la cual se deriva (hereda) del formulario y será la que usemos en nuestro proyecto. Como dicho formulario dispone de un evento para indicar (o notificar) lo que el usuario está haciendo con él, he creado una clase que se usará como segundo parámetro de dicho evento y tendrá ciertas propiedades (realmente son campos), para que en todo momento estemos informados de qué se está haciendo: qué botón se pulsa, que opciones se han seleccionado o que es lo que se ha escrito tanto en la caja del texto a buscar como en la caja del texto a poner (reemplazar).

Antes de ver el código, veamos el aspecto que tiene el formulario en tiempo de diseño:


El formulario de buscar/reemplazar en tiempo de diseño

Como podemos ver, tenemos dos combos, uno para el texto a buscar y otro para el de reemplazar, el usar combos en lugar de simples cajas de textos, es para poder ir acumulando lo que el usuario vaya escribiendo, si bien la clase no se encarga de almacenar el contenido, sino que ofrece dos propiedades (una para cada combo) mediante las que podemos asignar el contenido o recuperar lo que haya en esas listas usando un array de tipo String.
También tenemos un botón para buscar y dos para reemplazar, el primero se usará para reemplazar una sola vez y el segundo por si queremos reemplazar todas las coincidencias.
También tenemos dos opciones, una para indicar que se quiere coincidencias exactas de mayúsculas y minúsculas y otra para indicar que sólo se tengan en cuenta palabras completas.

Como tendremos ocasión de ver, la clase principal (BuscarReemplazar) además de tener propiedades para saber que es lo que hay escrito en los combos, (o asignar lo que queremos que contenga), o para asignar/recuperar las opciones, tiene varios métodos que nos permiten mostrar el formulario tanto en modo modal (como cuadro de diálogo) como en modo no modal, en este último caso, se usará un evento para notificar que se ha pulsando en cualquiera de los botones y al mismo tiempo nos informará del texto escrito en los dos combos y los valores de las dos opciones.
Esos métodos para mostrar el formulario tienen dos sobrecargas, una de ellas se usará para indicar el formulario "padre" o contenedor del cuadro de diálogo de buscar/reemplazar.

He de aclarar, que esta clase realmente no realiza búsquedas ni sustituciones, simplemente se usa para que el usuario escriba y seleccione lo que quiere hacer, pero lo que hagamos lo tendremos que escribir nosotros. El hacerlo así, es porque dependiendo de dónde vayamos a buscar, lo podremos hacer de una forma u otra. Por ejemplo, si usamos un control RichTextBox, éste nos ofrece métodos para poder realizar búsquedas (bastantes sofisticadas) en el texto que contiene.

A continuación muestro el código que podríamos usar para realizar una búsqueda en un RichTextBox llamado rtEditor usando el formulario en modo modal (tipo ShowDialog):

Private Sub mnuBuscar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBuscar.Click
    Dim dlgBuscar As New BuscarReemplazar
    '
    With dlgBuscar
        If rtEditor.SelectionLength > 0 Then
            queBuscar = rtEditor.SelectedText
        End If
        ' buscarAnt es un array con el texto que contendrá el combo
        If Me.buscarAnt.Length > 0 Then
            .ListaBuscar = Me.buscarAnt
        End If
        ' opbMayusculas, opbCompleta y queBuscar estarán declaradas a nivel formulario
        .Mayusculas = opbMayusculas
        .PalabraCompleta = opbCompleta
        .Buscar = queBuscar
        .Title = "Buscar"
        If .BuscarDialog(Me) = BuscarResults.Buscar Then
            queBuscar = .Buscar
            If queBuscar = "" Then Return
            ' recuperar las palabras del combo
            Me.buscarAnt = .ListaBuscar
            opbMayusculas = .Mayusculas
            opbCompleta = .PalabraCompleta
            opbRtbF = RichTextBoxFinds.None
            If opbMayusculas Then opbRtbF = RichTextBoxFinds.MatchCase
            If opbCompleta Then opbRtbF = opbRtbF Or RichTextBoxFinds.WholeWord
            ' realizar la búsqueda en el RichTextBox rtEditor
            opbUltima = rtEditor.SelectionStart + 1
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF)
        End If
    End With
    dlgBuscar.Close()
End Sub

 

En el caso de usar la clase para mostrar el formulario no modal, es decir, se mantendrá abierto hasta que el usuario lo cierre y se debe interactuar cada vez que el usuario pulse en los botones.
En este caso, voy a mostrarte un ejemplo de cómo usarlo para mostrar las opciones de reemplazar, aunque en el evento OpcionClick de la clase se tendrá en cuenta de que el usuario pulse en cualquiera de los botones (incluso en buscar):

Private Sub mnuReemplazar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuReemplazar.Click
    ' Reemplazar
    Dim dlgBuscar As New BuscarReemplazar
    ' Asignamos el manejador del evento de la clase
    AddHandler dlgBuscar.OpcionClick, AddressOf br_OpcionClick
    '
    With dlgBuscar
        If rtEditor.SelectionLength > 0 Then
            queBuscar = rtEditor.SelectedText
        End If
        If reemplazarAnt.Length > 0 Then
            .ListaReemplazar = reemplazarAnt
        End If
        If buscarAnt.Length > 0 Then
            .ListaBuscar = buscarAnt
        End If
        .Mayusculas = opbMayusculas
        .PalabraCompleta = opbCompleta
        .Buscar = queBuscar
        .Reemplazar = queReemplazar
        .Title = "Reemplazar"
        .ReemplazarShow(Me)
    End With
End Sub
'
Private Sub br_OpcionClick(ByVal sender As Object, ByVal e As BuscarReemplazarEventArgs)
    ' El botón pulsado
    Dim br As BuscarResults = e.BuscarResult
    If br = BuscarResults.Cancelado Then Return
    '
    ' asignar las opciones del formulario de búsqueda a las variables locales
    opbCompleta = e.PalabraCompleta
    opbMayusculas = e.Mayusculas
    queBuscar = e.Buscar
    queReemplazar = e.Reemplazar
    opbRtbF = RichTextBoxFinds.None
    If opbMayusculas Then opbRtbF = RichTextBoxFinds.MatchCase
    If opbCompleta Then opbRtbF = opbRtbF Or RichTextBoxFinds.WholeWord
    '
    If TypeOf sender Is BuscarReemplazar Then
        buscarAnt = CType(sender, BuscarReemplazar).ListaBuscar
        reemplazarAnt = CType(sender, BuscarReemplazar).ListaReemplazar
    End If
    '
    Me.Cursor = Cursors.WaitCursor
    '
    ' si es buscar, buscar la siguiente
    If br = BuscarResults.Buscar Then
        ' buscar siempre a partir de la posición del cursor
        opbUltima = rtEditor.SelectionStart + 1
        opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF)
    End If
    ' si es reemplazar
    If br = BuscarResults.Reemplazar Then
        If opbUltima < 0 Then opbUltima = rtEditor.SelectionStart + 1
        ' si es reemplazar y hay texto seleccionado
        If rtEditor.SelectedText = queBuscar Then
            ' reemplazar la actual
            rtEditor.SelectedText = queReemplazar
            ' y buscar la siguiente
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF)
        Else
            ' si no hay texto seleccionado, buscar la siguiente
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF)
            If opbUltima > -1 Then
                If rtEditor.SelectedText <> "" Then
                    rtEditor.SelectedText = queReemplazar
                    opbUltima += queReemplazar.Length
                End If
            End If
        End If
    ElseIf br = BuscarResults.ReemplazarTodos Then
        ' si es reemplazar todos, se cambiarán todos los que coincidan
        Dim t As Integer = 0
        opbUltima = 0
        While opbUltima > -1
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF)
            If opbUltima > -1 Then
                t += 1
                If rtEditor.SelectedText <> "" Then
                    rtEditor.SelectedText = queReemplazar
                    opbUltima += queReemplazar.Length
                Else
                    Exit While
                End If
            End If
        End While
        If t > 0 Then
            MessageBox.Show("Se han realizado " & t.ToString() & " sustituciones", "Reemplazar")
        End If
    End If
    Me.Cursor = Cursors.Default
End Sub

 

Nota:
Todo este código es usando Visual Basic, el ejemplo de C# te lo muestro después del código de la clase.

 

Bueno, pues estoy es lo que hay por ahora. En otra ocasión pondré un ejemplo completo, pero como en el ejemplo en el que he usado esta clase tiene otras cosas que te tengo que explicar, (como añadir una lista de los últimos ficheros abiertos en un editor de texto o averiguar el formato (codificación) del fichero a editar, etc.), pues eso, lo dejo para otro día y así poder mantener "en suspense".
Espero que al menos esto que te muestro hoy te sea de utilidad... esa es la intención.

Nos vemos.
Guillermo
Nerja, 1 de Noviembre de 2004

 

Nota:
En el código de C# he tenido que cambiar la declaración de los métodos protegidos buscarShow y reemplazarShow del formulario fBuscar, ya que en VB los declaré empezando en minúsculas, pero en la clase BuscarReemplazar los declaré empezando por mayúsculas, (por aquello de que son métodos públicos), y debido a que Visual Basic no hace distinciones entre mayúsculas y minúsculas, (aunque el editor de VS los mantenga tal y como lo hemos escrito), pues no hay ningún problema al compilar, incluso usando el atributo CLSCompliant.

Sin embargo C# si distingue las mayúsculas de las minúsculas, por tanto para el compilador de C# son dos nombres totalmente distintos y si se usa el atributo de compatibilidad con CLS (CLSCompliant), da un error indicando que el código no es compatible porque existen métodos "expuestos" que sólo se diferencian en las mayúsculas / minúsculas, por tanto, para seguir con las buenas costumbres de compatibilizar el código entre lenguajes, en C# esos dos métodos del formulario los he declarado escribiendo la primera letra en mayúsculas, para que el código sea compatible con otros lenguajes de .NET.

En ambos casos, los métodos de la clase BuscarReemplazar, están declarados usando Shadows (new en C#) ya que estos métodos ocultan a los que están declarados en la clase base.

 


Código para Visual Basic.NET (VB.NET)El código para VB .NET

El código está más o menos comentado para que tengas más claras las ideas.

 

Nota:
En mi proyecto, todo el código lo he incluido en el mismo fichero, pero el formulario es el que debe estar en la parte superior del mismo, al menos si vamos a trabajar con él desde Visual Studio .NET, ya que este IDE requiere que los formularios sean la primera de las clases que aparezca en el código.
Digo esto, porque en el código del formulario (el cual muestro completo), he incluido las importaciones necesarias para el funcionamiento de toda la clase.

 


La clase para el segundo parámetro del evento (y el delegado)

' Clase para el parámetro del evento
' Las propiedades (campos públicos) se usarán para informar de:
' las opciones seleccionadas, el texto de buscar o reemplazar y el botón pulsado
Public Class BuscarReemplazarEventArgs
    Inherits EventArgs
    '
    Public BuscarResult As BuscarResults
    Public Mayusculas As Boolean
    Public PalabraCompleta As Boolean
    Public Buscar As String
    Public Reemplazar As String
    '
    Public Sub New(ByVal resultado As BuscarResults)
        Me.BuscarResult = resultado
    End Sub
    Public Sub New(ByVal resultado As BuscarResults, _
                    ByVal mayusc As Boolean, ByVal completa As Boolean)
        Me.New(resultado)
        Me.Mayusculas = mayusc
        Me.PalabraCompleta = completa
    End Sub
    Public Sub New(ByVal resultado As BuscarResults, ByVal mayusc As Boolean, ByVal completa As Boolean, _
                    ByVal busc As String, ByVal reemp As String)
        Me.New(resultado, mayusc, completa)
        Me.Buscar = busc
        Me.Reemplazar = reemp
    End Sub
End Class
'
' Delegado para el evento de la clase
' (siempre hay que consrevar las buenas costumbres y recomendaciones de .NET)
Public Delegate Sub BuscarReemplazarDelegate(ByVal sender As Object, ByVal e As BuscarReemplazarEventArgs)

 

 

La enumeración para saber el botón pulsado (BuscarResults)

' Enumeración para indicar la acción realizada (que botón se ha pulsado)
Public Enum BuscarResults
    Buscar
    Reemplazar
    ReemplazarTodos
    Cancelado
End Enum

 

 

El código del formulario (fBuscar)

'------------------------------------------------------------------------------
' Formulario para realizar búsquedas y reemplazos                   (31/Oct/04)
'
' ©Guillermo 'guille' Som, 2004
'------------------------------------------------------------------------------
Option Explicit On 
Option Strict On

Imports Microsoft.VisualBasic
Imports System
Imports System.Windows.Forms

Public Class fBuscar
    Inherits System.Windows.Forms.Form
    '
    Public Sub New()
        MyBase.New()

        'El Diseñador de Windows Forms requiere esta llamada.
        InitializeComponent()

        'Agregar cualquier inicialización después de la llamada a InitializeComponent()

        ' Estas asignaciones están en el constructor para evitar efectos "indeseados"
        ' como por ejemplo que se pierda lo que se asigne a la propiedad Buscar.
        Me.cboReemplazar.Text = ""
        Me.cboBuscar.Text = ""
    End Sub
    '
#Region " Código generado por el Diseñador de Windows Forms "

    'Form reemplaza a Dispose para limpiar la lista de componentes.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Requerido por el Diseñador de Windows Forms
    Private components As System.ComponentModel.IContainer

    'NOTA: el Diseñador de Windows Forms requiere el siguiente procedimiento
    'Puede modificarse utilizando el Diseñador de Windows Forms. 
    'No lo modifique con el editor de código.
    '--------------------------------------------------------------------------
    ' Los declarados como Protected es porque se usan desde la clase principal
    '--------------------------------------------------------------------------
    Protected WithEvents cboBuscar As System.Windows.Forms.ComboBox
    Protected WithEvents cboReemplazar As System.Windows.Forms.ComboBox
    Private WithEvents btnReemplazar As System.Windows.Forms.Button
    Protected WithEvents chkMayusculas As System.Windows.Forms.CheckBox
    Protected WithEvents chkCompleta As System.Windows.Forms.CheckBox
    Private WithEvents btnBuscar As System.Windows.Forms.Button
    Private WithEvents btnCerrar As System.Windows.Forms.Button
    Private WithEvents btnReemplazarTodos As System.Windows.Forms.Button
    Private WithEvents labelBuscar As System.Windows.Forms.Label
    Private WithEvents labelReemplazar As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.labelBuscar = New System.Windows.Forms.Label
        Me.btnBuscar = New System.Windows.Forms.Button
        Me.cboBuscar = New System.Windows.Forms.ComboBox
        Me.cboReemplazar = New System.Windows.Forms.ComboBox
        Me.btnReemplazar = New System.Windows.Forms.Button
        Me.labelReemplazar = New System.Windows.Forms.Label
        Me.chkMayusculas = New System.Windows.Forms.CheckBox
        Me.btnCerrar = New System.Windows.Forms.Button
        Me.chkCompleta = New System.Windows.Forms.CheckBox
        Me.btnReemplazarTodos = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'labelBuscar
        '
        Me.labelBuscar.Location = New System.Drawing.Point(12, 16)
        Me.labelBuscar.Name = "labelBuscar"
        Me.labelBuscar.Size = New System.Drawing.Size(92, 20)
        Me.labelBuscar.TabIndex = 0
        Me.labelBuscar.Text = "&Buscar:"
        '
        'btnBuscar
        '
        Me.btnBuscar.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnBuscar.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnBuscar.Location = New System.Drawing.Point(323, 12)
        Me.btnBuscar.Name = "btnBuscar"
        Me.btnBuscar.Size = New System.Drawing.Size(100, 23)
        Me.btnBuscar.TabIndex = 6
        Me.btnBuscar.Text = "B&uscar siguiente"
        '
        'cboBuscar
        '
        Me.cboBuscar.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.cboBuscar.Location = New System.Drawing.Point(104, 12)
        Me.cboBuscar.Name = "cboBuscar"
        Me.cboBuscar.Size = New System.Drawing.Size(212, 21)
        Me.cboBuscar.TabIndex = 1
        Me.cboBuscar.Text = "ComboBox1"
        '
        'cboReemplazar
        '
        Me.cboReemplazar.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.cboReemplazar.Location = New System.Drawing.Point(104, 44)
        Me.cboReemplazar.Name = "cboReemplazar"
        Me.cboReemplazar.Size = New System.Drawing.Size(212, 21)
        Me.cboReemplazar.TabIndex = 3
        Me.cboReemplazar.Text = "ComboBox2"
        '
        'btnReemplazar
        '
        Me.btnReemplazar.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnReemplazar.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnReemplazar.Location = New System.Drawing.Point(323, 44)
        Me.btnReemplazar.Name = "btnReemplazar"
        Me.btnReemplazar.Size = New System.Drawing.Size(100, 23)
        Me.btnReemplazar.TabIndex = 7
        Me.btnReemplazar.Text = "R&eemplazar"
        '
        'labelReemplazar
        '
        Me.labelReemplazar.Location = New System.Drawing.Point(12, 48)
        Me.labelReemplazar.Name = "labelReemplazar"
        Me.labelReemplazar.Size = New System.Drawing.Size(92, 20)
        Me.labelReemplazar.TabIndex = 2
        Me.labelReemplazar.Text = "&Reemplazar con:"
        '
        'chkMayusculas
        '
        Me.chkMayusculas.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.chkMayusculas.Location = New System.Drawing.Point(8, 104)
        Me.chkMayusculas.Name = "chkMayusculas"
        Me.chkMayusculas.Size = New System.Drawing.Size(164, 20)
        Me.chkMayusculas.TabIndex = 4
        Me.chkMayusculas.Text = "&Mayúsculas / minúsculas"
        '
        'btnCerrar
        '
        Me.btnCerrar.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnCerrar.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnCerrar.Location = New System.Drawing.Point(324, 124)
        Me.btnCerrar.Name = "btnCerrar"
        Me.btnCerrar.Size = New System.Drawing.Size(100, 23)
        Me.btnCerrar.TabIndex = 9
        Me.btnCerrar.Text = "Cerrar"
        '
        'chkCompleta
        '
        Me.chkCompleta.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.chkCompleta.Location = New System.Drawing.Point(8, 128)
        Me.chkCompleta.Name = "chkCompleta"
        Me.chkCompleta.Size = New System.Drawing.Size(164, 20)
        Me.chkCompleta.TabIndex = 5
        Me.chkCompleta.Text = "&Palabras completas"
        '
        'btnReemplazarTodos
        '
        Me.btnReemplazarTodos.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnReemplazarTodos.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnReemplazarTodos.Location = New System.Drawing.Point(323, 76)
        Me.btnReemplazarTodos.Name = "btnReemplazarTodos"
        Me.btnReemplazarTodos.Size = New System.Drawing.Size(100, 23)
        Me.btnReemplazarTodos.TabIndex = 8
        Me.btnReemplazarTodos.Text = "Reemplazar &todos"
        '
        'fBuscar
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(434, 157)
        Me.Controls.Add(Me.btnReemplazarTodos)
        Me.Controls.Add(Me.chkCompleta)
        Me.Controls.Add(Me.btnCerrar)
        Me.Controls.Add(Me.chkMayusculas)
        Me.Controls.Add(Me.cboReemplazar)
        Me.Controls.Add(Me.btnReemplazar)
        Me.Controls.Add(Me.labelReemplazar)
        Me.Controls.Add(Me.cboBuscar)
        Me.Controls.Add(Me.btnBuscar)
        Me.Controls.Add(Me.labelBuscar)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "fBuscar"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.Manual
        Me.Text = "fBuscar"
        Me.ResumeLayout(False)

    End Sub

#End Region
    '
    ' Evento para notificar que se ha pulsado en un botón
    ' (se usará principalmente si no se muestra modal,
    ' para poder saber qué es lo que quiere hacer el usuario)
    Public Event OpcionClick As BuscarReemplazarDelegate
    '
    Protected Sub onOpcionClick(ByVal resultado As BuscarResults)
        ' La clase que se usa en el evento informará del botón pulsado,
        ' las opciones seleccionadas, además del texto de buscar y reemplazar
        Dim e As New BuscarReemplazarEventArgs(resultado)
        e.Mayusculas = chkMayusculas.Checked
        e.PalabraCompleta = chkCompleta.Checked
        e.Buscar = cboBuscar.Text
        e.Reemplazar = cboReemplazar.Text
        RaiseEvent OpcionClick(Me, e)
    End Sub
    '
    Private _buscarResult As BuscarResults
    Protected Property buscarResult() As BuscarResults
        Get
            Return _buscarResult
        End Get
        Set(ByVal value As BuscarResults)
            _buscarResult = value
            If Me.Modal Then
                ' si es modal, se oculta el formulario
                Hide()
            Else
                ' si no es modal, se produce el evento
                ' pero no se oculta el formulario
                onOpcionClick(_buscarResult)
            End If
        End Set
    End Property
    '
    '
    ' Mostrar para buscar (deshabilitar las opciones de reemplazar)
    Protected Sub buscarShow()
        labelReemplazar.Enabled = False
        cboReemplazar.Enabled = False
        btnReemplazar.Enabled = False
        btnReemplazarTodos.Enabled = False
    End Sub
    ' Mostrar para reemplazar
    ' (asegurarse de que estén todas las opciones habilitadas)
    Protected Sub reemplazarShow()
        labelReemplazar.Enabled = True
        cboReemplazar.Enabled = True
        btnReemplazar.Enabled = True
        btnReemplazarTodos.Enabled = True
    End Sub
    '
    Private Sub asignarListas()
        Dim s As String = cboBuscar.Text
        If s <> "" Then
            If cboBuscar.FindStringExact(s) = -1 Then
                cboBuscar.Items.Add(s)
            End If
        End If
        s = cboReemplazar.Text
        If s <> "" Then
            If cboReemplazar.FindStringExact(s) = -1 Then
                cboReemplazar.Items.Add(s)
            End If
        End If
    End Sub
    '
    ' Eventos privados del formulario
    ' Al pulsar en los botones de buscar, reemplazar o reemplazar todos
    ' se actualizan los elementos de los combos,
    ' para añadir la palabra tecleada si no estaba.
    ' En todos los casos:
    ' al asignar el valor a la propiedad buscarResult
    ' se ocultará la ventana o se producirá el evento, según se muestre modal o no
    Private Sub btnBuscar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBuscar.Click
        asignarListas()
        buscarResult = BuscarResults.Buscar
    End Sub
    '
    Private Sub btnReemplazar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReemplazar.Click
        asignarListas()
        buscarResult = BuscarResults.Reemplazar
    End Sub
    '
    Private Sub btnReemplazarTodos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReemplazarTodos.Click
        asignarListas()
        buscarResult = BuscarResults.ReemplazarTodos
    End Sub
    '
    Private Sub btnCerrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCerrar.Click
        buscarResult = BuscarResults.Cancelado
        Close()
    End Sub
    '
    Private Sub fBuscar_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        _buscarResult = BuscarResults.Cancelado
        onOpcionClick(_buscarResult)
    End Sub
End Class

 

 

La clase principal (BuscarReemplazar)

' La clase "recomendada" para usar el formulario de búsqueda/reemplazo
' Se derivará del formulario de buscar y expondrá métodos amigables para mostrar el formulario
Public NotInheritable Class BuscarReemplazar
    Inherits fBuscar
    '
    Public Sub New()
        MyBase.New()
    End Sub
    '
    ' Los métodos acabados en Dialog se usarán para mostrar el formulario modal
    ' Los métodos acabados en Show   se usarán para mostrar el formulario no modal (interactivo)
    ' Cuando se usa modal no se produce el evento OpcionClick,
    ' en no modal, se utiliza el evento para saber que ha sucedido algo.
    ' En todos los casos existirá una sobrecarga en la que se puede indicar el formulario "padre"
    '
    ' Muestra sólo las opciones de buscar (en modal, tipo diálogo)
    Public Function BuscarDialog() As BuscarResults
        MyBase.buscarShow()
        ShowDialog()
        Return buscarResult
    End Function
    Public Function BuscarDialog(ByVal fOwner As Form) As BuscarResults
        MyBase.buscarShow()
        StartPosition = FormStartPosition.CenterParent
        ShowDialog(fOwner)
        Return buscarResult
    End Function
    '
    ' Muestra las opciones de buscar y reemplazar (en modal, tipo diálogo)
    Public Function ReemplazarDialog() As BuscarResults
        MyBase.reemplazarShow()
        ShowDialog()
        Return buscarResult
    End Function
    Public Function ReemplazarDialog(ByVal fOwner As Form) As BuscarResults
        MyBase.reemplazarShow()
        StartPosition = FormStartPosition.CenterParent
        ShowDialog(fOwner)
        Return buscarResult
    End Function
    '
    ' Muestra sólo las opciones de buscar (no modal)
    ' Al usar los métodos no modales, se interactúa con el usuario
    ' mediante el evento OpcionClick
    Public Shadows Sub BuscarShow()
        MyBase.buscarShow()
        Show()
    End Sub
    Public Shadows Sub BuscarShow(ByVal fOwner As Form)
        MyBase.buscarShow()
        '
        ' para centrarlo
        'MyBase.Left = (fOwner.Left + MyBase.Width) \ 2
        'MyBase.Top = (fOwner.Top + MyBase.Height) \ 2
        ' posicionarlo en la esquina inferior derecha
        'MyBase.Left = fOwner.Left + fOwner.Width - MyBase.Width
        'MyBase.Top = fOwner.Top + fOwner.Height - MyBase.Height
        '
        If fOwner.Width + fOwner.Left + Width < Screen.PrimaryScreen.WorkingArea.Width Then
            ' Si hay ancho suficiente mostrarlo a la derecha del principal
            Left = fOwner.Left + fOwner.Width
            Top = fOwner.Top
        ElseIf fOwner.Height + fOwner.Top + Height < Screen.PrimaryScreen.WorkingArea.Height Then
            ' Si hay altura suficiente mostrarlo debajo del principal
            Top = fOwner.Top + fOwner.Height
            Left = fOwner.Left + fOwner.Width - Width
        Else
            ' En otro caso, posicionarlo en la esquina superior derecha
            Left = fOwner.Left + fOwner.Width - Width
            Top = 0
        End If
        '
        Show()
    End Sub
    '
    ' Muestra las opciones de buscar y reemplazar (no modal)
    Public Shadows Sub ReemplazarShow()
        MyBase.reemplazarShow()
        Show()
    End Sub
    Public Shadows Sub ReemplazarShow(ByVal fOwner As Form)
        MyBase.reemplazarShow()
        '
        If fOwner.Width + fOwner.Left + Width < Screen.PrimaryScreen.WorkingArea.Width Then
            Left = fOwner.Left + fOwner.Width '+ 1
            Top = fOwner.Top
        ElseIf fOwner.Height + fOwner.Top + Height < Screen.PrimaryScreen.WorkingArea.Height Then
            Top = fOwner.Top + fOwner.Height '+ 1
            Left = fOwner.Left + fOwner.Width - Width
        Else
            Left = fOwner.Left + fOwner.Width - Width
            Top = 0
        End If
        '
        Show()
    End Sub
    '
    ' El título a mostrar en el formulario
    Public Property Title() As String
        Get
            Return Text
        End Get
        Set(ByVal value As String)
            Text = value
        End Set
    End Property
    '
    ' Cerrar el formulario
    Public Shadows Sub Close()
        MyBase.Close()
    End Sub
    '
    ' Las propiedades para las opciones y textos a buscar/reemplazar
    ' (las pongo en esta clase para "obligar" a usarla en lugar del formulario)
    '
    ' El texto a buscar
    Public Property Buscar() As String
        Get
            Return cboBuscar.Text
        End Get
        Set(ByVal value As String)
            cboBuscar.Text = value
        End Set
    End Property
    ' El texto indicado para reemplazar
    Public Property Reemplazar() As String
        Get
            Return cboReemplazar.Text
        End Get
        Set(ByVal value As String)
            cboReemplazar.Text = value
        End Set
    End Property
    '
    ' La opción de comprobar mayúsculas/minúsculas
    Public Property Mayusculas() As Boolean
        Get
            Return chkMayusculas.Checked
        End Get
        Set(ByVal value As Boolean)
            chkMayusculas.Checked = value
        End Set
    End Property
    ' La opción de comprobar palabras completas
    Public Property PalabraCompleta() As Boolean
        Get
            Return chkCompleta.Checked
        End Get
        Set(ByVal value As Boolean)
            chkCompleta.Checked = value
        End Set
    End Property
    '
    ' Asignar o recuperar los elementos del combo de buscar
    Public Property ListaBuscar() As String()
        Get
            Dim a(cboBuscar.Items.Count - 1) As String
            For i As Integer = 0 To cboBuscar.Items.Count - 1
                a(i) = cboBuscar.Items(i).ToString
            Next
            Return a
        End Get
        Set(ByVal value As String())
            cboBuscar.Items.Clear()
            For i As Integer = value.Length - 1 To 0 Step -1
                cboBuscar.Items.Add(value(i))
            Next
        End Set
    End Property
    ' Asignar o recuperar los elementos del combo de reemplazar
    Public Property ListaReemplazar() As String()
        Get
            Dim a(cboReemplazar.Items.Count - 1) As String
            For i As Integer = 0 To cboReemplazar.Items.Count - 1
                a(i) = cboReemplazar.Items(i).ToString
            Next
            Return a
        End Get
        Set(ByVal value As String())
            cboReemplazar.Items.Clear()
            For i As Integer = value.Length - 1 To 0 Step -1
                cboReemplazar.Items.Add(value(i))
            Next
        End Set
    End Property
End Class

 

 


Código para C Sharp (C#)El código para C#

El código está más o menos comentado para que tengas más claras las ideas.

 

La clase para el segundo parámetro del evento (y el delegado)

// Clase para el parámetro del evento
// Las propiedades (campos públicos) se usarán para informar de:
// las opciones seleccionadas, el texto de buscar o reemplazar y el botón pulsado
public class BuscarReemplazarEventArgs : EventArgs
{
    //
    public BuscarResults BuscarResult;
    public bool Mayusculas;
    public bool PalabraCompleta;
    public string Buscar;
    public string Reemplazar;
    //
    public BuscarReemplazarEventArgs(BuscarResults resultado) 
    {
        this.BuscarResult = resultado;
    }  
    public BuscarReemplazarEventArgs(BuscarResults resultado, bool mayusc, bool completa)
	 : this(resultado) 
    {
        this.Mayusculas = mayusc;
        this.PalabraCompleta = completa;
    }  
    public BuscarReemplazarEventArgs(BuscarResults resultado, bool mayusc, bool completa, string busc, string reemp)
	 : this(resultado, mayusc, completa) 
    {
        this.Buscar = busc;
        this.Reemplazar = reemp;
    }  
}
//
// Delegado para el evento de la clase
// (siempre hay que conservar las buenas costumbres y recomendaciones de .NET)
public delegate void BuscarReemplazarDelegate(object sender, BuscarReemplazarEventArgs e);

 

 

La enumeración para saber el botón pulsado (BuscarResults)

// Enumeración para indicar la acción realizada (que botón se ha pulsado)
public enum BuscarResults
{
    Buscar,
    Reemplazar,
    ReemplazarTodos,
    Cancelado
};

 

 

El código del formulario (fBuscar)

//------------------------------------------------------------------------------
// Formulario para realizar búsquedas y reemplazos                   (01/Nov/04)
//
// Código convertido de Visual Basic usando VCB2CS2003
//
// ©Guillermo 'guille' Som, 2004
//------------------------------------------------------------------------------
using System;
using System.Windows.Forms;
 
public class fBuscar : System.Windows.Forms.Form
{
    //
    public fBuscar()
    {
         //El Diseñador de Windows Forms requiere esta llamada.
        InitializeComponent();
 
        btnBuscar.Click += new System.EventHandler(btnBuscar_Click);
        btnReemplazar.Click += new System.EventHandler(btnReemplazar_Click);
        btnReemplazarTodos.Click += new System.EventHandler(btnReemplazarTodos_Click);
        btnCerrar.Click += new System.EventHandler(btnCerrar_Click);
        base.Closing += new System.ComponentModel.CancelEventHandler(fBuscar_Closing);

        //Agregar cualquier inicialización después de la llamada a InitializeComponent()
        this.cboReemplazar.Text = "";
        this.cboBuscar.Text = "";
    }  
    //
    #region Código generado por el Diseñador de Windows Forms
 
    //Form reemplaza a Dispose para limpiar la lista de componentes.
    protected override void Dispose(bool disposing) 
    {
        if( disposing )
        {
            if( ! (components == null) )
            {
                components.Dispose();
            }
        }
        base.Dispose(disposing);
    }  
 
    //Requerido por el Diseñador de Windows Forms
    private System.ComponentModel.IContainer components = null;
 
    //NOTA: el Diseñador de Windows Forms requiere el siguiente procedimiento
    //Puede modificarse utilizando el Diseñador de Windows Forms.
    //No lo modifique con el editor de código.
    protected System.Windows.Forms.ComboBox cboBuscar;
    protected System.Windows.Forms.ComboBox cboReemplazar;
    private System.Windows.Forms.Button btnReemplazar;
    protected System.Windows.Forms.CheckBox chkMayusculas;
    protected System.Windows.Forms.CheckBox chkCompleta;
    private System.Windows.Forms.Button btnBuscar;
    private System.Windows.Forms.Button btnCerrar;
    private System.Windows.Forms.Button btnReemplazarTodos;
    private System.Windows.Forms.Label labelBuscar;
    private System.Windows.Forms.Label labelReemplazar;
    [System.Diagnostics.DebuggerStepThrough()]private void InitializeComponent() 
    {
        this.labelBuscar = new System.Windows.Forms.Label();
        this.btnBuscar = new System.Windows.Forms.Button();
        this.cboBuscar = new System.Windows.Forms.ComboBox();
        this.cboReemplazar = new System.Windows.Forms.ComboBox();
        this.btnReemplazar = new System.Windows.Forms.Button();
        this.labelReemplazar = new System.Windows.Forms.Label();
        this.chkMayusculas = new System.Windows.Forms.CheckBox();
        this.btnCerrar = new System.Windows.Forms.Button();
        this.chkCompleta = new System.Windows.Forms.CheckBox();
        this.btnReemplazarTodos = new System.Windows.Forms.Button();
        this.SuspendLayout();
        //
        //labelBuscar
        //
        this.labelBuscar.Location = new System.Drawing.Point(12, 16);
        this.labelBuscar.Name = "labelBuscar";
        this.labelBuscar.Size = new System.Drawing.Size(92, 20);
        this.labelBuscar.TabIndex = 0;
        this.labelBuscar.Text = "&Buscar:";
        //
        //btnBuscar
        //
        this.btnBuscar.Anchor = (( System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
        this.btnBuscar.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.btnBuscar.Location = new System.Drawing.Point(323, 12);
        this.btnBuscar.Name = "btnBuscar";
        this.btnBuscar.Size = new System.Drawing.Size(100, 23);
        this.btnBuscar.TabIndex = 6;
        this.btnBuscar.Text = "B&uscar siguiente";
        //
        //cboBuscar
        //
        this.cboBuscar.Anchor = (( System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right));
        this.cboBuscar.Location = new System.Drawing.Point(104, 12);
        this.cboBuscar.Name = "cboBuscar";
        this.cboBuscar.Size = new System.Drawing.Size(212, 21);
        this.cboBuscar.TabIndex = 1;
        this.cboBuscar.Text = "ComboBox1";
        //
        //cboReemplazar
        //
        this.cboReemplazar.Anchor = (( System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right));
        this.cboReemplazar.Location = new System.Drawing.Point(104, 44);
        this.cboReemplazar.Name = "cboReemplazar";
        this.cboReemplazar.Size = new System.Drawing.Size(212, 21);
        this.cboReemplazar.TabIndex = 3;
        this.cboReemplazar.Text = "ComboBox2";
        //
        //btnReemplazar
        //
        this.btnReemplazar.Anchor = (( System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
        this.btnReemplazar.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.btnReemplazar.Location = new System.Drawing.Point(323, 44);
        this.btnReemplazar.Name = "btnReemplazar";
        this.btnReemplazar.Size = new System.Drawing.Size(100, 23);
        this.btnReemplazar.TabIndex = 7;
        this.btnReemplazar.Text = "R&eemplazar";
        //
        //labelReemplazar
        //
        this.labelReemplazar.Location = new System.Drawing.Point(12, 48);
        this.labelReemplazar.Name = "labelReemplazar";
        this.labelReemplazar.Size = new System.Drawing.Size(92, 20);
        this.labelReemplazar.TabIndex = 2;
        this.labelReemplazar.Text = "&Reemplazar con:";
        //
        //chkMayusculas
        //
        this.chkMayusculas.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.chkMayusculas.Location = new System.Drawing.Point(8, 104);
        this.chkMayusculas.Name = "chkMayusculas";
        this.chkMayusculas.Size = new System.Drawing.Size(164, 20);
        this.chkMayusculas.TabIndex = 4;
        this.chkMayusculas.Text = "&Mayúsculas / minúsculas";
        //
        //btnCerrar
        //
        this.btnCerrar.Anchor = (( System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right));
        this.btnCerrar.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.btnCerrar.Location = new System.Drawing.Point(324, 124);
        this.btnCerrar.Name = "btnCerrar";
        this.btnCerrar.Size = new System.Drawing.Size(100, 23);
        this.btnCerrar.TabIndex = 9;
        this.btnCerrar.Text = "Cerrar";
        //
        //chkCompleta
        //
        this.chkCompleta.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.chkCompleta.Location = new System.Drawing.Point(8, 128);
        this.chkCompleta.Name = "chkCompleta";
        this.chkCompleta.Size = new System.Drawing.Size(164, 20);
        this.chkCompleta.TabIndex = 5;
        this.chkCompleta.Text = "&Palabras completas";
        //
        //btnReemplazarTodos
        //
        this.btnReemplazarTodos.Anchor = (( System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
        this.btnReemplazarTodos.FlatStyle = System.Windows.Forms.FlatStyle.System;
        this.btnReemplazarTodos.Location = new System.Drawing.Point(323, 76);
        this.btnReemplazarTodos.Name = "btnReemplazarTodos";
        this.btnReemplazarTodos.Size = new System.Drawing.Size(100, 23);
        this.btnReemplazarTodos.TabIndex = 8;
        this.btnReemplazarTodos.Text = "Reemplazar &todos";
        //
        //fBuscar
        //
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(434, 157);
        this.Controls.Add(this.btnReemplazarTodos);
        this.Controls.Add(this.chkCompleta);
        this.Controls.Add(this.btnCerrar);
        this.Controls.Add(this.chkMayusculas);
        this.Controls.Add(this.cboReemplazar);
        this.Controls.Add(this.btnReemplazar);
        this.Controls.Add(this.labelReemplazar);
        this.Controls.Add(this.cboBuscar);
        this.Controls.Add(this.btnBuscar);
        this.Controls.Add(this.labelBuscar);
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
        this.MaximizeBox = false;
        this.MinimizeBox = false;
        this.Name = "fBuscar";
        this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        this.Text = "fBuscar";
        this.ResumeLayout(false);
     }  
     #endregion
    //
    // Evento para notificar que se ha pulsado en un botón
    // (se usará principalmente si no se muestra modal,
    // para poder saber qué es lo que quiere hacer el usuario)
    public event BuscarReemplazarDelegate OpcionClick;
    //
    protected void onOpcionClick(BuscarResults resultado) 
    {
        // La clase que se usa en el evento informará del botón pulsado,
        // las opciones seleccionadas, además del texto de buscar y reemplazar
        BuscarReemplazarEventArgs e = new BuscarReemplazarEventArgs(resultado);
        e.Mayusculas = chkMayusculas.Checked;
        e.PalabraCompleta = chkCompleta.Checked;
        e.Buscar = cboBuscar.Text;
        e.Reemplazar = cboReemplazar.Text;
        if( OpcionClick != null ) OpcionClick(this, e);
    }  
    //
    private BuscarResults _buscarResult;
    protected BuscarResults buscarResult 
    {
        get
        {
            return _buscarResult;
        }
        set
        {
            _buscarResult = value;
            if( this.Modal )
            {
                // si es modal, se oculta el formulario
                Hide();
            }
            else
            {
                // si no es modal, se produce el evento
                // pero no se oculta el formulario
                onOpcionClick(_buscarResult);
            }
        }
    }  
    //
    // Mostrar para buscar (deshabilitar las opciones de reemplazar)
    protected void BuscarShow() 
    {
        labelReemplazar.Enabled = false;
        cboReemplazar.Enabled = false;
        btnReemplazar.Enabled = false;
        btnReemplazarTodos.Enabled = false;
    }  
    // Mostrar para reemplazar
    // (asegurarse de que estén todas las opciones habilitadas)
    protected void ReemplazarShow() 
    {
        labelReemplazar.Enabled = true;
        cboReemplazar.Enabled = true;
        btnReemplazar.Enabled = true;
        btnReemplazarTodos.Enabled = true;
    }  
    //
    private void asignarListas() 
    {
        string s = cboBuscar.Text;
        if( s != "" )
        {
            if( cboBuscar.FindStringExact(s) == -1 )
            {
                cboBuscar.Items.Add(s);
            }
        }
        s = cboReemplazar.Text;
        if( s != "" )
        {
            if( cboReemplazar.FindStringExact(s) == -1 )
            {
                cboReemplazar.Items.Add(s);
            }
        }
    }  
    //
    // Eventos privados del formulario
    // Al pulsar en los botones de buscar, reemplazar o reemplazar todos
    // se actualizan los elementos de los combos,
    // para añadir la palabra tecleada si no estaba.
    // En todos los casos:
    // al asignar el valor a la propiedad buscarResult
    // se ocultará la ventana o se producirá el evento, según se muestre modal o no
    private void btnBuscar_Click(System.Object sender, System.EventArgs e) 
    {
        asignarListas();
        buscarResult = BuscarResults.Buscar;
    }  
    //
    private void btnReemplazar_Click(System.Object sender, System.EventArgs e) 
    {
        asignarListas();
        buscarResult = BuscarResults.Reemplazar;
    }  
    //
    private void btnReemplazarTodos_Click(System.Object sender, System.EventArgs e) 
    {
        asignarListas();
        buscarResult = BuscarResults.ReemplazarTodos;
    }  
    //
    private void btnCerrar_Click(System.Object sender, System.EventArgs e) 
    {
        buscarResult = BuscarResults.Cancelado;
        Close();
    }  
    //
    private void fBuscar_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    {
        _buscarResult = BuscarResults.Cancelado;
        onOpcionClick(_buscarResult);
    }  
}

 

 

La clase principal (BuscarReemplazar)

// La clase "recomendada" para usar el formulario de búsqueda/reemplazo
// Se derivará del formulario de buscar y expondrá métodos amigables para mostrar el formulario
public sealed class BuscarReemplazar : fBuscar
{
    //
    public BuscarReemplazar()
    {
    }  
    //
    // Los métodos acabados en Dialog se usarán para mostrar el formulario modal
    // Los métodos acabados en Show   se usarán para mostrar el formulario no modal (interactivo)
    // Cuando se usa modal no se produce el evento OpcionClick,
    // en no modal, se utiliza el evento para saber que ha sucedido algo.
    // En todos los casos existirá una sobrecarga en la que se puede indicar el formulario "padre"
    //
    // Muestra sólo las opciones de buscar (en modal, tipo diálogo)
    public BuscarResults BuscarDialog() 
    {
        base.BuscarShow();
        ShowDialog();
        return buscarResult;
    }  
    public BuscarResults BuscarDialog(Form fOwner) 
    {
        base.BuscarShow();
        StartPosition = FormStartPosition.CenterParent;
        ShowDialog(fOwner);
        return buscarResult;
    }  
    //
    // Muestra las opciones de buscar y reemplazar (en modal, tipo diálogo)
    public BuscarResults ReemplazarDialog() 
    {
        base.ReemplazarShow();
        ShowDialog();
        return buscarResult;
    }  
    public BuscarResults ReemplazarDialog(Form fOwner) 
    {
        base.ReemplazarShow();
        StartPosition = FormStartPosition.CenterParent;
        ShowDialog(fOwner);
        return buscarResult;
    }  
    //
    // Muestra sólo las opciones de buscar (no modal)
    // Al usar los métodos no modales, se interactúa con el usuario
    // mediante el evento OpcionClick
    public new void BuscarShow() 
    {
        base.BuscarShow();
        Show();
    }  
    public void BuscarShow(Form fOwner) 
    {
        base.BuscarShow();
        //
        if( fOwner.Width + fOwner.Left + Width < Screen.PrimaryScreen.WorkingArea.Width )
        {
            // Si hay ancho suficiente mostrarlo a la derecha del principal
            Left = fOwner.Left + fOwner.Width;
            Top = fOwner.Top;
        }
        else if( fOwner.Height + fOwner.Top + Height < Screen.PrimaryScreen.WorkingArea.Height )
        {
            // Si hay altura suficiente mostrarlo debajo del principal
            Top = fOwner.Top + fOwner.Height;
            Left = fOwner.Left + fOwner.Width - Width;
        }
        else
        {
            // En otro caso, posicionarlo en la esquina superior derecha
            Left = fOwner.Left + fOwner.Width - Width;
            Top = 0;
        }
        //
        Show();
    }  
    //
    // Muestra las opciones de buscar y reemplazar (no modal)
    public new void ReemplazarShow() 
    {
        base.ReemplazarShow();
        Show();
    }  
    public void ReemplazarShow(Form fOwner) 
    {
        base.ReemplazarShow();
        //
        if( fOwner.Width + fOwner.Left + Width < Screen.PrimaryScreen.WorkingArea.Width )
        {
            Left = fOwner.Left + fOwner.Width; //+ 1
            Top = fOwner.Top;
        }
        else if( fOwner.Height + fOwner.Top + Height < Screen.PrimaryScreen.WorkingArea.Height )
        {
            Top = fOwner.Top + fOwner.Height; //+ 1
            Left = fOwner.Left + fOwner.Width - Width;
        }
        else
        {
            Left = fOwner.Left + fOwner.Width - Width;
            Top = 0;
        }
        //
        Show();
    }  
    //
    // El título a mostrar en el formulario
    public string Title 
    {
        get{ return Text; }
        set{ Text = value; }
    }  
    //
    // Cerrar el formulario
    public new void Close() 
    {
        base.Close();
    }  
    //
    // Las propiedades para las opciones y textos a buscar/reemplazar
    // (las pongo en esta clase para "obligar" a usarla en lugar del formulario)
    //
    // El texto a buscar
    public string Buscar 
    {
        get{ return cboBuscar.Text; }
        set{ cboBuscar.Text = value; }
    }  
    // El texto indicado para reemplazar
    public string Reemplazar 
    {
        get{ return cboReemplazar.Text; }
        set{ cboReemplazar.Text = value; }
    }  
    //
    // La opción de comprobar mayúsculas/minúsculas
    public bool Mayusculas 
    {
        get{ return chkMayusculas.Checked; }
        set{ chkMayusculas.Checked = value; }
    }  
    // La opción de comprobar palabras completas
    public bool PalabraCompleta 
    {
        get{ return chkCompleta.Checked; }
        set{ chkCompleta.Checked = value; }
    }  
    //
    // Asignar o recuperar los elementos del combo de buscar
    public String[] ListaBuscar 
    {
        get
        { 
            string[] a = new string[(cboBuscar.Items.Count - 1 + 1)];
            for(int i= 0; i<= cboBuscar.Items.Count - 1; i++)
                a[i] = cboBuscar.Items[i].ToString();
            return a;
        }
        set
        {
            cboBuscar.Items.Clear();
            for(int i= value.Length - 1; i>= 0; i--)
                cboBuscar.Items.Add(value[i]);
        }
    }  
    // Asignar o recuperar los elementos del combo de reemplazar
    public String[] ListaReemplazar 
    {
        get
        {
            string[] a = new string[(cboReemplazar.Items.Count - 1 + 1)];
            for(int i= 0; i<= cboReemplazar.Items.Count - 1; i++)
                a[i] = cboReemplazar.Items[i].ToString();
            return a;
        }
        set
        {
            cboReemplazar.Items.Clear();
            for(int i= value.Length - 1; i>= 0; i--)
                cboReemplazar.Items.Add(value[i]);
        }
    }  
}

 

 


El código de ejemplo para usar la clase
(como el del código de VB mostrado en el artículo)

Primer ejemplo: Buscar usando el formulario modal.

private void mnuBuscar_Click(System.Object sender, System.EventArgs e) 
{
    BuscarReemplazar dlgBuscar = new BuscarReemplazar();
    //
    if( rtEditor.SelectionLength > 0 )
        queBuscar = rtEditor.SelectedText;
    // buscarAnt es un array con el texto que contendrá el combo
    if( this.buscarAnt.Length > 0 )
        dlgBuscar.ListaBuscar = this.buscarAnt;
    // opbMayusculas, opbCompleta y queBuscar estarán declaradas a nivel formulario
    dlgBuscar.Mayusculas = opbMayusculas;
    dlgBuscar.PalabraCompleta = opbCompleta;
    dlgBuscar.Buscar = queBuscar;
    dlgBuscar.Title = "Buscar";
    if( dlgBuscar.BuscarDialog(this) == BuscarResults.Buscar )
    {
        queBuscar = dlgBuscar.Buscar;
        if( queBuscar == "" ) return;
        // recuperar las palabras del combo
        this.buscarAnt = dlgBuscar.ListaBuscar;
        opbMayusculas = dlgBuscar.Mayusculas;
        opbCompleta = dlgBuscar.PalabraCompleta;
        opbRtbF = RichTextBoxFinds.None;
        if( opbMayusculas ) opbRtbF = RichTextBoxFinds.MatchCase;
        if( opbCompleta ) opbRtbF = opbRtbF | RichTextBoxFinds.WholeWord;
        // realizar la búsqueda en el RichTextBox rtEditor
        opbUltima = rtEditor.SelectionStart + 1;
        opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF);
    }
    dlgBuscar.Close();
}

 

Segundo ejemplo: Reemplazar usando el formulario no modal y el evento

private void mnuReemplazar_Click(System.Object sender, System.EventArgs e) 
{
    // Buscar/Reemplazar
    BuscarReemplazar dlgBuscar = new BuscarReemplazar();
    dlgBuscar.OpcionClick += new BuscarReemplazarDelegate(br_OpcionClick);
    //
    if( rtEditor.SelectionLength > 0 )
        queBuscar = rtEditor.SelectedText;
    if( this.reemplazarAnt.Length > 0 )
        dlgBuscar.ListaReemplazar = this.reemplazarAnt;
    if( this.buscarAnt.Length > 0 )
        dlgBuscar.ListaBuscar = this.buscarAnt;
    dlgBuscar.Mayusculas = opbMayusculas;
    dlgBuscar.PalabraCompleta = opbCompleta;
    dlgBuscar.Buscar = queBuscar;
    dlgBuscar.Reemplazar = queReemplazar;
    dlgBuscar.Title = "Reemplazar";
    dlgBuscar.ReemplazarShow(this);
}  
//
private void br_OpcionClick(object sender, BuscarReemplazarEventArgs e)
{
    // El botón pulsado
    BuscarResults br = e.BuscarResult;
    if( br == BuscarResults.Cancelado ) return;
    //
    // asignaar las opciones del formulario de búsqueda a las variables locales
    opbCompleta = e.PalabraCompleta;
    opbMayusculas = e.Mayusculas;
    queBuscar = e.Buscar;
    queReemplazar = e.Reemplazar;
    opbRtbF = RichTextBoxFinds.None;
    if( opbMayusculas ) opbRtbF = RichTextBoxFinds.MatchCase;
    if( opbCompleta ) opbRtbF = opbRtbF | RichTextBoxFinds.WholeWord;
    //
    if( sender is BuscarReemplazar )
    {
        this.buscarAnt = (( BuscarReemplazar)sender).ListaBuscar;
        this.reemplazarAnt = (( BuscarReemplazar)sender).ListaReemplazar;
    }
    //
    this.Cursor = Cursors.WaitCursor;
    //
    // si es buscar, buscar la siguiente
    if( br == BuscarResults.Buscar )
    {
        // buscar siempre a partir de la posición del cursor
        opbUltima = rtEditor.SelectionStart + 1;
        opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF);
    }
    // si es reemplazar
    if( br == BuscarResults.Reemplazar )
    {
        if( opbUltima < 0 ) opbUltima = rtEditor.SelectionStart + 1;
        // si es reemplazar y hay texto seleccionado
        if( rtEditor.SelectedText == queBuscar )
        {
            // reemplazar la actual
            rtEditor.SelectedText = queReemplazar;
            // y buscar la siguiente
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF);
        }else{
            // si no hay texto seleccionado, buscar la siguiente
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF);
            if( opbUltima > -1 )
            {
                if( rtEditor.SelectedText != "" )
                {
                    rtEditor.SelectedText = queReemplazar;
                    opbUltima += queReemplazar.Length;
                }
            }
        }
    }else if( br == BuscarResults.ReemplazarTodos )
    {
        // si es reemplazar todos, se cambiarán todos los que coincidan
        int t = 0;
        opbUltima = 0;
        while( opbUltima > -1)
        {
            opbUltima = rtEditor.Find(queBuscar, opbUltima, opbRtbF);
            if( opbUltima > -1 )
            {
                t += 1;
                if( rtEditor.SelectedText != "" )
                {
                    rtEditor.SelectedText = queReemplazar;
                    opbUltima += queReemplazar.Length;
                }else
                    break;
            }
        }
        if( t > 0 )
            MessageBox.Show("Se han realizado " + t.ToString() + " sustituciones", "Reemplazar");
    }
    this.Cursor = Cursors.Default;
}

 


la Luna del Guille o... el Guille que está en la Luna... tanto monta...