Wpf – RibbonComboBox y SelectedItem

Descripción general

Este artículo pretende aclarar cómo se puede usar el control RibbonComboBox, y la propiedad SelectedItem del mismo.

[TOC] Tabla de Contenidos


↑↑↑

1.1 Introducción

Cuando uno se enfrenta a la cinta Ribbon , aparecen una serie de controles "nuevos" que se comportan de la forma esperada, hasta que te tropiezas con el control [RibbonComboBox] y entonces es cuando te acuerdas de todos los diseñadores y de sus santas madres. ¿No podían haber escrito una interfaz similar al control [ComboBox] estándar para evitarnos problemas? Pues no, han tenido que inventar algo nuevo para descolocarnos a todos.

El problema que resuelve este documento es como cargar los datos de un [RibbonComboBox] y como disparar e interceptar el evento [SelectedItem].


↑↑↑

1.2 Carga de un combo Box (Código Xaml)

El ejemplo que proporciona Microsoft está en: [RibbonComboBox (Clase)]

Aquí tienes otro ejemplo sobre el que vamos a trabajar

<Custom:RibbonComboBox 
         Label="Lista de dedos" 
         SelectionBoxWidth="62" 
         VerticalAlignment="Center" 
         IsEditable="True" >
   <Custom:RibbonGallery 
            SelectedValue="Corazón" 
            SelectedValuePath="Content" 
            MaxColumnCount="1">
          <Custom:RibbonGalleryCategory >
                  <Custom:RibbonGalleryItem Content="Pulgar"  />
                  <Custom:RibbonGalleryItem Content="Indice"  />
                  <Custom:RibbonGalleryItem Content="Corazón" />
                  <Custom:RibbonGalleryItem Content="Anular"  />
                  <Custom:RibbonGalleryItem Content="Menique" />
          </Custom:RibbonGalleryCategory>
   </Custom:RibbonGallery>
</Custom:RibbonComboBox>

En el apreciamos que para llegar a los elementos ComboBoxItem, que ahora se llaman [RibbonGalleryItem], hay que pasar por una nueva serie de elementos [RibbonComboBox], [RibbonGallery],y [RibbonGalleryCategory] y por fin [RibbonGalleryItem] que es el que realmente contiene el dato que muestra el combo Box

Observa que a cada elemento le he dado un nombre para poder acceder a ellos desde el codigo

Y así es como se muestra en la cinta Ribbon.

Falta el texto Alt de la imagen

Falta el texto Alt de la imagen


↑↑↑

1.2.1 El evento [SelectionChanged]

Vale pero ahora quiero saber que elemento es el que se ha elegido en el [RibbonComboBox], para, por ejemplo, poner ese valor en un TextBox para ello tendré que usar el evento [SelectionChanged], y aquí es donde aparece el problema, ¿Dónde está ese evento?, que elemento de los cuatro que hay en el árbol del [RibbonComboBox] lo dispara?

IMPORTANTE

1.2.1.1 Aquí puedes ver el código Xaml del RibbonComboBox

<Custom:RibbonComboBox 
         Label="Lista de dedos" 
         SelectionBoxWidth="62" 
         VerticalAlignment="Center" 
         IsEditable="True" >
   <Custom:RibbonGallery 
              x:Name="RibbonGalleryListaDeDedosEjemploUno" 
              SelectedValue="Corazón" 
              SelectedValuePath="Content" 
              MaxColumnCount="1" 
              SelectionChanged="RibbonGalleryListaDeDedosEjemploUno_SelectionChanged">
          <Custom:RibbonGalleryCategory >
                 <Custom:RibbonGalleryItem Content="Pulgar"  />
                 <Custom:RibbonGalleryItem Content="Indice"  />
                 <Custom:RibbonGalleryItem Content="Corazón" />
                 <Custom:RibbonGalleryItem Content="Anular"  />
                 <Custom:RibbonGalleryItem Content="Menique" />
          </Custom:RibbonGalleryCategory>
   </Custom:RibbonGallery>
</Custom:RibbonComboBox>

Observa que he tenido que darle un nombre al elemento [RibbonGallery] para poder generar un nombre de evento coherente

1.2.1.2 Y aquí puedes ver el código (Vb.net) que lo intercepta

Private Sub RibbonGalleryListaDeDedosEjemploUno_SelectionChanged(
    ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Object))

    Dim source As RibbonGallery = Nothing
    source = TryCast(e.OriginalSource, RibbonGallery)

        If source Is Nothing Then
            Return
        End If

        Dim texto As String
        Dim RgCat As RibbonGalleryItem = CType(source.SelectedItem, RibbonGalleryItem)
        texto = CType(RgCat.Content, String)

        ' ahora muevo este texto a un control TextBox (por ejemplo)
        RibbonTextBoxResultado.Text = texto
    End Sub

↑↑↑

1.3 Carga de un combo Box desde código

Hay veces que me interesa cargar un RibbonComboBox box desde código, por ejemplo, supongamos que quiero cargar en el combo todos los nombres de las fuentes disponibles en Windows

 
<WrapPanel>
     <Custom:RibbonComboBox 
     SelectionBoxWidth="100">
           <Custom:RibbonGallery 
                            x:Name="RibbonGalleryFuentesWindows" 
                            SelectionChanged="RibbonGalleryFuentesWindows_SelectionChanged">
               <Custom:RibbonGalleryCategory 
                                    x:Name="RibbonGalleryCategoryFuentesWindows"/>
         </Custom:RibbonGallery>
     </Custom:RibbonComboBox>

     <Custom:RibbonComboBox 
         SelectionBoxWidth="40">
           <Custom:RibbonGallery
                                  x:Name="RibbonGalleryTamañoPixelFuente"
                                  SelectionChanged="RibbonGalleryTamañoPixelFuente_SelectionChanged">
             <Custom:RibbonGalleryCategory 
                              x:Name="RibbonGalleryCategoryTamañoPixelFuente"/>
         </Custom:RibbonGallery>
     </Custom:RibbonComboBox>
 </WrapPanel>
Public Sub InitcializarFuentesWindows()
    RibbonGalleryCategoryFuentesWindows.ItemsSource = System.Windows.Media.Fonts.SystemFontFamilies
    'RibbonGalleryFuentesWindows.SelectedItem = "Arial"
    RibbonGalleryFuentesWindows.SelectedItem = New System.Windows.Media.FontFamily("Arial")

    For i As Double = 8 To 47 Step 2
        RibbonGalleryCategoryTamañoPixelFuente.Items.Add(i)
    Next
    'RibbonGalleryTamañoPixelFuente.SelectedItem = "8"
End Sub

↑↑↑

1.4 Carga de un combo Box desde código

Otras veces necesito (quiero) cargar en un combo los valores de una enumeración, por ejemplo supongamos la enumeración Dedos

Public Enum DedosE
    Pulgar
    Indice
    Corazón
    Anular
    Menique
End Enum

↑↑↑

1.4.1 Xaml

Para cargarla en el combo box tendremos que escribir el código Xaml como sigue:

<Custom:RibbonComboBox 
        x:Name="RibbonComboBoxDedos" 
        VerticalAlignment="Top" 
        SelectionBoxWidth="180" >
 
        <Custom:RibbonGallery 
                        x:Name="RibbonGalleryDedos" 
                        MaxColumnCount="1" 
                        SelectionChanged ="RibbonComboBoxDedosSelectionChanged">
              <Custom:RibbonGalleryCategory 
                                    x:Name="RibbonGalleryCategoryDedos" />
                      <!-- Este [RibbonComboBox] Se carga por código -->
        </Custom:RibbonGallery>
</Custom:RibbonComboBox>

↑↑↑

1.4.2 Carga Combo por código

Y el código que carga la enumeración puede adoptar varias variantes, y lo peor es que según la opción que escojamos, el objeto que devuelve el evento SelectionChanged es diferente

1.4.2.1 Opcion uno

Private Sub CargarEnumeracionDedosEUno()
    RibbonGalleryCategoryDedos.Items.Clear()
    RibbonGalleryCategoryDedos.Items.Add(DedosE.Pulgar.ToString)
    RibbonGalleryCategoryDedos.Items.Add(DedosE.Indice.ToString)
    RibbonGalleryCategoryDedos.Items.Add(DedosE.Corazón.ToString)
    RibbonGalleryCategoryDedos.Items.Add(DedosE.Anular.ToString)
    RibbonGalleryCategoryDedos.Items.Add(DedosE.Menique.ToString)
    RibbonGalleryDedos.SelectedItem = (DedosE.Corazón.ToString)
End Sub

1.4.2.2 Opcion dos

Private Sub CargarEnumeracionDedosEDos()

    RibbonGalleryCategoryDedos.Items.Clear()

    ' cargar la matriz en el ribbon combo box
    ' definir el objeto [RibbonGalleryItem] que es cada uno de 
    ' los elementos del ribbon combo box
    Dim unRibbonGalleryItem As Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem

    unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
    unRibbonGalleryItem.Content = DedosE.Pulgar.ToString
    RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)

    unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
    unRibbonGalleryItem.Content = DedosE.Indice.ToString
    '   ' seleccionar este elemento 
    unRibbonGalleryItem.IsSelected = True
    RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)

    unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
    unRibbonGalleryItem.Content = DedosE.Corazón.ToString
    RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)

    unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
    unRibbonGalleryItem.Content = DedosE.Anular.ToString
    RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)

    unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
    unRibbonGalleryItem.Content = DedosE.Menique.ToString
    RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)

    ''   ' seleccionar el elemento 2 del ribbon Combo box 
    'unRibbonGalleryItem = CType(ComboBoxRibbonGalleryCategoryDedos.Items.Item(2),
    Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem)
    'unRibbonGalleryItem.IsSelected = True

End Sub

1.4.2.3 Opcion tres

Private Sub CargarEnumeracionDedosETres()
    ' la enumeración que se carga
    Dim unaEnumeracion As DedosE = DedosE.Indice
    'La matriz de cadena donde se recogen los nombres de las constantes enumeradas
    Dim MatrizCadena() As String

    ' Vaciar el ribbon combo Box
    RibbonGalleryCategoryDedos.Items.Clear()
    ' cargar la enumeración en una matriz
    MatrizCadena = [Enum].GetNames(unaEnumeracion.GetType)

    ' cargar la matriz en el ribbon combo box
    ' definir el objeto [RibbonGalleryItem] que es cada uno de los elementos del ribbon combo box
    Dim unRibbonGalleryItem As Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem

    ' recorrer la matriz y cargar el ribbonCombobox
    For Each cadena In MatrizCadena
        unRibbonGalleryItem = New Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem
        unRibbonGalleryItem.Content = cadena
        RibbonGalleryCategoryDedos.Items.Add(unRibbonGalleryItem)
    Next

    ' seleccionar el elemento 1 del ribbon Combo box 
    unRibbonGalleryItem = CType(RibbonGalleryCategoryDedos.Items.Item(1), _
    Microsoft.Windows.Controls.Ribbon.RibbonGalleryItem)
    unRibbonGalleryItem.IsSelected = True
End Sub

↑↑↑

1.4.3 Evento SelectionChanged

Al final, el evento SelectionChanged que funcionan con todos es el siguiente

Private Sub RibbonComboBoxDedosSelectionChanged(
    Byval sender As Object,
    Byval  e As RoutedPropertyChangedEventArgs(Of Object))

    Dim source As RibbonGallery = Nothing
    source = TryCast(e.OriginalSource, RibbonGallery)

        If source Is Nothing Then
            Return
        End If

        Dim texto As String = String.Empty

        Select Case source.SelectedItem.GetType
            Case = GetType(RibbonGalleryItem)
                ' si doy de alta el objeto [RibbonGalleryItem] en el combo
                Dim RGItem As RibbonGalleryItem = CType(source.SelectedItem, RibbonGalleryItem)
                texto = CType(RGItem.Content, String)

            Case Is = GetType(System.String)
                texto = CType(source.SelectedItem, String)

            Case Else
                Using sw As New System.IO.StringWriter
                    sw.WriteLine("Problemas en SelectionChanged")
                    sw.WriteLine("El tipo recibido es:  [{0}]",
                    source.SelectedItem.GetType.ToString)
                    sw.Flush()
                    Throw New ArgumentException(sw.ToString)
                End Using
        End Select

        'Mover la información a un cuadro de texto
        RibbonTextBoxResultado.Text = texto

    End Sub

↑↑↑

1.5 Bibliografía

WPF RibbonComboBox Selection


↑↑↑

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]