Usar interfaces con Commands

 

Problema

Necesito acceder a las propiedades de un control, (por ejemplo, borrar el contenido de un TextBox), y uso (que va a ser que si) un [Command] independiente en una clase (es decir, no escribo el [Command] en el modelo-vista), lo que ocurre es que al hacer el Binding, tengo que pasar a través del parámetro [CommandParameter] el objeto completo, es decir, el TextBox, el botón u lo que sea,

 

En este caso: dentro del command escribiré la siguiente función [Execute]:

 

    ''' <summary>

    '''    Esta función Borra todo el texto de un textBox pasado por parámetro

    ''' </summary>

    Private Sub cmdExecute(ByVal parameter As Object)

        If parameter IsNot Nothing Then

            Dim target As TextBox = TryCast(parameter, TextBox)

            If target IsNot Nothing Then

                If target.Text.Length > 0 Then

                    target.Clear()

                End If

            End If

        End If

    End Sub

 

Observa que lo primero que hago, es comprobar que el valor del parámetro no sea Nothing, de esta forma evito errores tontos.

Después convierto el [Objeto] en un [TextBox], y por ultimo uso la propiedad del control que me interesa, en este caso la de borrar el contenido del texto.

Entonces… ¿Dónde está el problema?

Pues que cuando diseño controles de usuario, para aplicar un [Command] necesito pasar TODO el control de usuario para hacer el casting.

Supongamos que diseño un control con un cuadro de texto multi-línea  y varios botones, para mostrar (por ejemplo) poesías de una forma determinada, otro control para mostrar textos cifrados, etc. Si quiero usar un Command que borre el cuadro de texto del control deberé escribir un Command para cada uno de los controles, y siendo una operación tan sencilla y común (como borrar un cuadro de texto) debería poder hacerse con un único Command.

Después de darle muchas vueltas me he dado cuenta de que puedo usar interfaces con lo que el código se generaliza y puedo reutilizarlo

Ejemplo la siguiente interfaz define dos métodos muy usados en los cuadro de texto, y por lo tanto en todos los controles que tengan cuadros de texto como componente principal

 

 

''' <summary>

'''  Interface para ser usada por controles compuestos

'''  que quieran usar las clases Command

''' </summary>

Public Interface IControlCommand

 

    ''' <summary>

    '''  Obtiene establece la propiedad [Text] del

    '''  cuadro de texto del control

    ''' </summary>

    Property ZText As String

 

    ''' <summary>

    '''  Limpia [borra], el contenido del cuadro

    '''  de texto del control

    ''' </summary>

    Sub ZClear()

 

End Interface

 

Nota.: el que las propiedades tengan la letra zeta [Z ]delante es para poder distinguirlas rápidamente en el diseñador, y además, sane todas juntas y al final de todo :-)

En el control compuesto que estoy escribiendo, implementare la Interfaz

Imagen del control compuesto que tiene varios controles internos y una funcionalidad definida

Public Class UserControlPrueba

    Implements IControlCommand

 

 

 

    Public Property ZText As String Implements IControlCommand.ZText

        Get

            Return Me.TextBoxInterno.Text

        End Get

        Set(value As String)

            Me.TextBoxInterno.Text = value

        End Set

    End Property

 

 

    Public Sub ZClear() Implements IControlCommand.ZClear

        Me.TextBoxInterno.Clear()

    End Sub

 

 

End Class

 

Y la clase Command que borraría el cuadro de texto del control quedaría así:

 

''' <summary>

'''   Borra el contenido de un TextBox

''' </summary>

Public NotInheritable Class ControlClearTextBoxCommand

    Inherits DelegateCommand

    Implements IDisposable

 

 

    Public Property LocalGesture As KeyGesture

 

    Public Sub New()

        MyBase.New()

 

        '-------------------------------

        ' Los parametros de [Commnad]

        ' El [Delegado] (la Accion) que llamara al metodo [cmdExecute]

        Dim localExcuteAction As Action(Of Object) =

                              New Action(Of Object)(AddressOf Me.cmdExecute)

        ' El [Delegado] que llamara al metodo [cmdCanExecute]

        Dim localCanExecuteAction As Predicate(Of Object) =

                             Function(param) Me.cmdCanExecute(param)

        ' el nombre de este command

        Dim localNombreCommand As String = "TextBoxBorraTextoCommand"

        '  Juego de teclas que activan el comando (P.e: Ctrl + D)

 

        LocalGesture = New KeyGesture(Key.D, ModifierKeys.Control, "Borrar [Ctrl+D]")

 

        '-------------------------------

        MyBase._nombreCommand = localNombreCommand

        MyBase._executeAction = localExcuteAction

        MyBase._canExecuteAction = localCanExecuteAction

 

    End Sub

 

 

 

    ''' <summary>

    '''    Esta funcion Borra todo el texto de un textBox pasado por parametro

    ''' </summary>

    Private Sub cmdExecute(ByVal parameter As Object)

        If parameter IsNot Nothing Then

            Dim target As IControlCommand = TryCast(parameter, IControlCommand)

            'target.TextBoxInterno.Clear()

            target.ZText = String.Empty

        End If

    End Sub

 

    ''' <summary>

    '''    Esta funcion Comprueba que en  TextBox haya un texto

    '''    para poder ejecutar la funcion [Execute]

    '''    Si hay un texto devuelve (True) [Si se puede ejecutar],

    '''    si no hay texto devuelve false [No se puede ejecutar]

    ''' </summary>

    Private ReadOnly Property cmdCanExecute(ByVal parameter As Object) As Boolean

        Get

            Dim resultado As Boolean = False

            If parameter IsNot Nothing Then

                Dim target As IControlCommand = TryCast(parameter, IControlCommand)

                If target IsNot Nothing Then

                    If target.ZText.Length > 0 Then

                        resultado = True

                    End If

                End If

            End If

            Return resultado

        End Get

    End Property

 

 

 

#Region "IDisposable Support"

    Private _disposedValue As Boolean ' Para detectar llamadas redundantes

 

    ' IDisposable

    Protected Overloads Sub Dispose(disposing As Boolean)

        If Not Me._disposedValue Then

            If disposing Then

                MyBase.Dispose()

            End If

        End If

        Me._disposedValue = True

    End Sub

#End Region

 

End Class

 

 

Por último el código XAML del formulario que contiene el control y un botón que borra el cuadro de texto interno del control seria así:

<Window

  x:Class="MainWindow"

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:local="clr-namespace:WpfPruebaEnlaceControlesUsuario"

  Title="MainWindow" Height="313" Width="246">

 

  <Window.Resources>

    <local:ControlClearTextBoxCommand x:Key=" ControlClearTextBoxCommandResources " />

  </Window.Resources>

 

  <Grid>

      <local:UserControlPrueba x:Name="UCPrueba"

                               HorizontalAlignment="Left"  

                               VerticalAlignment="Top"

                               Margin="10"/>

     

      <Button x:Name="ButtonBorrarForm" Content="Button"

              HorizontalAlignment="Center" VerticalAlignment="Bottom"

              Margin="10" Width="75"

 

              Command="{Binding Mode=OneWay,

                     Source={StaticResource ControlClearTextBoxCommandResources }}"

 

              CommandParameter="{Binding ElementName=UCPrueba,

                                 Mode=OneWay,

                                 ValidatesOnNotifyDataErrors=False}"

 

              CommandTarget="{Binding ElementName=UCPrueba,

                                 Mode=OneWay,

                                 ValidatesOnNotifyDataErrors=False}"  />

  </Grid>

</Window>

 

Imagen del formulario antes y después de pulsar el botón mostrando que el command funciona :-) usando interfaces

 

 


↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquín Medina Serrano
Ésta página es española

Codificación
Fecha de creación
Última actualización
[HTML5 Desarrollado usando CSS3]