¿Cómo mostrar el texto predeterminado "--Seleccionar equipo -" en el cuadro combinado al cargar la página en WPF?


109

En una aplicación WPF, en la aplicación MVP, tengo un cuadro combinado, para el cual muestro los datos obtenidos de la base de datos. Antes de los elementos agregados al cuadro combinado, quiero mostrar el texto predeterminado, como

" -- Selecciona un equipo --"

para que al cargar la página se muestre y al seleccionarlo se borre el texto y se muestren los elementos.

Está sucediendo la selección de datos de la base de datos. Necesito mostrar el texto predeterminado hasta que el usuario seleccione un elemento del cuadro combinado.

Por favor guíame

Respuestas:


107

La forma más fácil que he encontrado para hacer esto es:

<ComboBox Name="MyComboBox"
 IsEditable="True"
 IsReadOnly="True"
 Text="-- Select Team --" />

Obviamente, necesitará agregar sus otras opciones, pero esta es probablemente la forma más sencilla de hacerlo.

Sin embargo, hay una desventaja de este método que es que, si bien el texto dentro de su cuadro combinado no será editable, aún se puede seleccionar. Sin embargo, dada la mala calidad y complejidad de todas las alternativas que he encontrado hasta la fecha, esta es probablemente la mejor opción que existe.


¡Gran respuesta Chris! Solo agregaría Focusable = "True", pero eso es solo un cambio cosmético.
Slavisa

6
respuesta perfecta Chris. Una propiedad puede hacer una gran diferencia: D
Aster Veigas

4
Focusable="False" IsEditable="True" IsReadOnly="True"
Kamil Lelonek

1
+1. Lamentablemente, no funciona con elementos mixtos (por ejemplo, si los elementos del cuadro combinado son imágenes).
greenoldman

11
Solución simple y funcional. Los controles de WPF tienen este tipo de problemas en todo el marco. Aquí y allá, a los controles les faltan características que la mayoría de los desarrolladores necesitarían. Como resultado, los desarrolladores pierden el tiempo buscando soluciones, comprando controles alternativos de terceros o implementando soluciones ... ¿El equipo de WPF incluso usa sus controles para sus propios desarrollos?
Malditas verduras

90

Puede hacer esto sin ningún código detrás usando un IValueConverter.

<Grid>
   <ComboBox
       x:Name="comboBox1"
       ItemsSource="{Binding MyItemSource}"  />
   <TextBlock
       Visibility="{Binding SelectedItem, ElementName=comboBox1, Converter={StaticResource NullToVisibilityConverter}}"
       IsHitTestVisible="False"
       Text="... Select Team ..." />
</Grid>

Aquí tienes la clase de convertidor que puedes reutilizar.

public class NullToVisibilityConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

Y finalmente, debe declarar su convertidor en una sección de recursos.

<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />

Donde Convertidores es el lugar donde ha colocado la clase de convertidor. Un ejemplo es:

xmlns:Converters="clr-namespace:MyProject.Resources.Converters"

Lo bueno de este enfoque es que no hay repetición de código en su código subyacente.


Me gustaría usar esto, pero parece que no está permitido en los casos en que el cuadro combinado es el encabezado de una cuadrícula de datos. . . XAML da un error de que el encabezado ya está definido (o quizás no se puede definir más de una vez). ¿Algunas ideas? Estoy pensando solo en usar una opción de valor nulo, que luego permitirá un restablecimiento al seleccionarla, pero parece un poco descuidado.
Paul Gibson

1
Una gran razón por la que esta es una solución excelente es porque casi todos los proyectos de WPF vinculados a datos utilizan un NullToVisibilityConverter, por lo que ya está allí la mayor parte del tiempo, ¡también podría usarlo!
tpartee

2
En realidad, puede usar un DataTriggerpara evitar incluso el código del convertidor aquí :)
Billy ONeal

49

Me gusta la respuesta de Tri Q, pero esos convertidores de valor son difíciles de usar. PaulB lo hizo con un controlador de eventos, pero eso también es innecesario. Aquí hay una solución XAML pura:

<ContentControl Content="{Binding YourChoices}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox x:Name="cb" ItemsSource="{Binding}"/>
                <TextBlock x:Name="tb" Text="Select Something" IsHitTestVisible="False" Visibility="Hidden"/>
            </Grid>
            <DataTemplate.Triggers>
                <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                </Trigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate> 
</ContentControl>

33

Nadie dijo que una solución xaml pura tiene que ser complicada. Aquí hay uno simple, con 1 disparador de datos en el cuadro de texto. Margen y posición como se desee

<Grid>
    <ComboBox x:Name="mybox" ItemsSource="{Binding}"/>
    <TextBlock Text="Select Something" IsHitTestVisible="False">
           <TextBlock.Style>
                <Style TargetType="TextBlock">
                      <Setter Property="Visibility" Value="Hidden"/>
                      <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=mybox,Path=SelectedItem}" Value="{x:Null}">
                                  <Setter Property="Visibility" Value="Visible"/>
                             </DataTrigger>
                      </Style.Triggers>
                </Style>
           </TextBlock.Style>
     </TextBlock>
</Grid>

5
Necesitaba mover "Visibility =" Hidden "en el activador de datos. Luego funcionó como se esperaba. Definitivamente el enfoque más directo que he visto. Para la reutilización, moví el estilo a un recurso
Mitch

La respuesta de @Mitch IceForce no me funciona, ¿qué cambiaste para que funcionara?
Chris

1
@Chris Creo que se refería a agregar <Setter Property="Visibility" Value="Hidden"/>fuera del activador (dentro del estilo) y eliminar Visibility="Hidden"del elemento de bloque de texto real
restablezca a Monica, por favor

@Mitch, ¿cómo se mueve el estilo Textblock a un recurso para reutilizarlo si tiene ElementName en el DataTrigger apuntando a un objeto específico (mybox)? ¿Hay alguna forma de especificar ese nombre de forma genérica?
CrApHeR

24

Establecer IsEditable="True"en el ComboBoxelemento. Esto mostrará la Textpropiedad de ComboBox.


2
Esta es la solución más simple de todas.
Sergey Koulikov

6
Sin embargo, sí cambia el aspecto del control
simonalexander2005

16

No sé si es compatible directamente, pero puede superponer el combo con una etiqueta y configurarlo como oculto si la selección no es nula.

p.ej.

<Grid>
   <ComboBox Text="Test" Height="23" SelectionChanged="comboBox1_SelectionChanged" Name="comboBox1" VerticalAlignment="Top" ItemsSource="{Binding Source=ABCD}"  />
   <TextBlock IsHitTestVisible="False" Margin="10,5,0,0" Name="txtSelectTeam" Foreground="Gray" Text="Select Team ..."></TextBlock>
</Grid>

Luego, en la selección cambió el controlador ...

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    txtSelectTeam.Visibility = comboBox1.SelectedItem == null ? Visibility.Visible : Visibility.Hidden;
}

1
En lugar de hacer un controlador SelectionChanged, la visibilidad de TextBlock podría establecerse en XAML.
aliceraunsbaek

6

Basado en la respuesta de IceForge, preparé una solución reutilizable:

estilo xaml:

<Style x:Key="ComboBoxSelectOverlay" TargetType="TextBlock">
    <Setter Property="Grid.ZIndex" Value="10"/>
    <Setter Property="Foreground" Value="{x:Static SystemColors.GrayTextBrush}"/>
    <Setter Property="Margin" Value="6,4,10,0"/>
    <Setter Property="IsHitTestVisible" Value="False"/>
    <Setter Property="Visibility" Value="Hidden"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding}" Value="{x:Null}">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

ejemplo de uso:

<Grid>
     <ComboBox x:Name="cmb"
               ItemsSource="{Binding Teams}" 
               SelectedItem="{Binding SelectedTeam}"/>
     <TextBlock DataContext="{Binding ElementName=cmb,Path=SelectedItem}"
               Text=" -- Select Team --" 
               Style="{StaticResource ComboBoxSelectOverlay}"/>
</Grid>

Agradable. Lo he extendido vinculando el DataContext de TextBlock usando una fuente relativa para evitar tener que establecer el nombre. Vea el siguiente comentario para Markup (el código en los comentarios de SO se ve feo)
Sascha

<TextBlock DataContext = "{Binding Path = Children [0] .SelectedItem, RelativeSource = {RelativeSource AncestorType = Grid}}" Text = "- Seleccionar proyecto -" Style = "{StaticResource ComboBoxSelectOverlay}" />
Sascha

4

No lo probé con cuadros combinados, pero esto me ha funcionado con otros controles ...

publicación de blog ageektrapped

Utiliza la capa de adorno aquí para mostrar una marca de agua.


Acabo de descargar y probar este código. Parece funcionar como se anuncia. Le permite decorar su combo con una propiedad adjunta simple que contiene su marca de agua. También funciona para otros controles. Es un enfoque mucho mejor que cualquiera de las otras respuestas a esta pregunta.
Ian Oakes

Buenas cosas, no solo resuelve el problema de ComboBox, sino que ahora puedo deshacerme del ensamblaje de WPF Tools y usar esto en mis TextBoxes en lugar del control WatermarkedTextBox también, tan lleno de ganancias :) - oh por cierto, no es A Geek Trapped ¡Trampa de acuerdo!
2012

2

La solución de HappyNomad fue muy buena y finalmente me ayudó a llegar a esta solución ligeramente diferente.

<ComboBox x:Name="ComboBoxUploadProject" 
    Grid.Row="2"
    Width="200" 
    Height="23"                           
    Margin="64,0,0,0"
    ItemsSource="{Binding projectList}"
    SelectedValue ="{Binding projectSelect}" 
    DisplayMemberPath="projectName"
    SelectedValuePath="projectId"
    >
    <ComboBox.Template>
        <ControlTemplate TargetType="ComboBox">
            <Grid>
                <ComboBox x:Name="cb" 
                    DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" 
                    ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
                    SelectedValue ="{Binding SelectedValue, RelativeSource={RelativeSource TemplatedParent}}" 
                    DisplayMemberPath="projectName"
                    SelectedValuePath="projectId"
                    />
                <TextBlock x:Name="tb" Text="Select Item..." Margin="3,3,0,0" IsHitTestVisible="False" Visibility="Hidden"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </ComboBox.Template>
</ComboBox>

2

La forma más sencilla es utilizar CompositeCollection para fusionar el texto y los datos predeterminados de la base de datos directamente en ComboBox, por ejemplo

    <ComboBox x:Name="SelectTeamComboBox" SelectedIndex="0">
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <ComboBoxItem Visibility="Collapsed">-- Select Team --</ComboBoxItem>
                <CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=MyComboOptions}}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>

Y en Recursos, defina StaticResource para vincular las opciones de ComboBox a su DataContext, porque el enlace directo en CollectionContainer no funciona correctamente.

<Window.Resources>
    <CollectionViewSource Source="{Binding}" x:Key="MyComboOptions" />
</Window.Resources>

De esta manera, puede definir sus opciones de ComboBox solo en xaml, por ejemplo

   <ComboBox x:Name="SelectTeamComboBox" SelectedIndex="0">
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <ComboBoxItem Visibility="Collapsed">-- Select Team --</ComboBoxItem>
                <ComboBoxItem >Option 1</ComboBoxItem>
                <ComboBoxItem >Option 2</ComboBoxItem>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>

1

Recomendaría lo siguiente:

Definir un comportamiento

public static class ComboBoxBehaviors
{
    public static readonly DependencyProperty DefaultTextProperty =
        DependencyProperty.RegisterAttached("DefaultText", typeof(String), typeof(ComboBox), new PropertyMetadata(null));

    public static String GetDefaultText(DependencyObject obj)
    {
        return (String)obj.GetValue(DefaultTextProperty);
    }

    public static void SetDefaultText(DependencyObject obj, String value)
    {
        var combo = (ComboBox)obj;

        RefreshDefaultText(combo, value);

        combo.SelectionChanged += (sender, _) => RefreshDefaultText((ComboBox)sender, GetDefaultText((ComboBox)sender));

        obj.SetValue(DefaultTextProperty, value);
    }

    static void RefreshDefaultText(ComboBox combo, string text)
    {
        // if item is selected and DefaultText is set
        if (combo.SelectedIndex == -1 && !String.IsNullOrEmpty(text))
        {
            // Show DefaultText
            var visual = new TextBlock()
            {
                FontStyle = FontStyles.Italic,
                Text = text,
                Foreground = Brushes.Gray
            };

            combo.Background = new VisualBrush(visual)
            {
                Stretch = Stretch.None,
                AlignmentX = AlignmentX.Left,
                AlignmentY = AlignmentY.Center,
                Transform = new TranslateTransform(3, 0)
            };
        }
        else
        {
            // Hide DefaultText
            combo.Background = null;
        }
    }
}

Usuario el comportamiento

<ComboBox Name="cmb" Margin="72,121,0,0" VerticalAlignment="Top"
          local:ComboBoxBehaviors.DefaultText="-- Select Team --"/>

Esto funciona como un encanto para un solo cuadro combinado. Pero cuando lo uso con más de 1 combo, me da un error (pero se compila y funciona bien) "Propiedad 'DefaultText' ya registrada por 'ComboBox'". He mencionado la solución en mi blog.
Romesh D. Niriella

Gracias por señalar esto. No pude producir este error en mi computadora. Sin embargo, acepto que typeof (ComboBoxBehaviors) debe pasarse en el tercer parámetro de RegisterAttached en lugar de typeof (ComboBox).
Usman Zafar

Aunque esta publicación es un poco antigua, no veo cómo puede funcionar. El bg del combo se establece a través de activadores con múltiples condiciones. Intente colocar un combo solo en una cuadrícula y establezca manualmente bg en 'rojo'. No tiene ningún efecto en el área donde desea que aparezca una marca de agua. Solo puede afectar al bg detrás del panel desplegable. Una mejor solución es copiar la plantilla de control del cuadro combinado y agregar algunos desencadenadores y estilos para pintar un pincel visual que consiste en un bloque de texto en el fondo del borde.
Newclique

1

La respuesta de IceForge fue bastante cercana, y es AFAIK la solución más fácil a este problema. Pero se perdió algo, ya que no estaba funcionando (al menos para mí, nunca muestra el texto).

Al final, no puede simplemente establecer la propiedad "Visibilidad" del TextBlock en "Oculto" para que se oculte cuando el elemento seleccionado del cuadro combinado no sea nulo; tienes que CONFIGURARlo de esa manera por defecto (ya que no puedes marcar no nulo en los disparadores , usando un Setter en XAML en el mismo lugar que los desencadenadores.

Aquí está la solución real basada en la suya, el Setter faltante se coloca justo antes de los Triggers:

<ComboBox x:Name="combo"/>
<TextBlock Text="--Select Team--" IsHitTestVisible="False">
    <TextBlock.Style>
        <Style TargetType="TextBlock">

            <Style.Setters>
                <Setter Property="Visibility" Value="Hidden"/>
            </Style.Setters>

            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=combo,Path=SelectedItem}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

1

EDITAR: Según los comentarios a continuación, esta no es una solución. No estoy seguro de cómo lo hice funcionar y no puedo verificar ese proyecto.

Es hora de actualizar esta respuesta para la última versión de XAML.

Al encontrar esta pregunta SO buscando una solución a esta pregunta, descubrí que la especificación XAML actualizada tiene una solución simple.

Un atributo llamado "Marcador de posición" ahora está disponible para realizar esta tarea. Es tan simple como esto (en Visual Studio 2015):

<ComboBox x:Name="Selection" PlaceholderText="Select...">
    <x:String>Item 1</x:String>
    <x:String>Item 2</x:String>
    <x:String>Item 3</x:String>
</ComboBox>

Usé esta solución, ¿le importa al votante negativo dar más detalles? De acuerdo, no soy un experto en XAML, pero funcionó.
Robb Sadler

1
Aunque no soy el votante en contra, me imagino que fue votado en contra porque no hay PlaceholderTextpropiedad en la System.Windows.ComboBoxclase . Esta es una pregunta sobre WPF, no sobre WinForms.
Sheridan

Hombre, esto es extraño, sé que estaba trabajando en una aplicación XAML, y sé que acababa de descubrir esto y lo vi funcionar. ¿Quizás se incluyó una extensión en el proyecto? IDK: desde entonces he buscado y seguro que no hay un marcador de posición en ComboBox. No puedo volver al proyecto en el que estaba trabajando: antiguo cliente. ugh.
Robb Sadler

2
No te equivocas, pero eso no es para WPF. UWP ComboBox tiene esto, consulte esta página: msdn.microsoft.com/en-us/library/windows/apps/…
laishiekai

0

No es la mejor práctica ... pero funciona bien ...

<ComboBox GotFocus="Focused"  x:Name="combobox1" HorizontalAlignment="Left" Margin="8,29,0,0" VerticalAlignment="Top" Width="128" Height="117"/>

Código detrás

public partial class MainWindow : Window
{
    bool clearonce = true;
    bool fillonce = true;
    public MainWindow()
    {
        this.InitializeComponent();          
        combobox1.Items.Insert(0, " -- Select Team --");
        combobox1.SelectedIndex = 0;
    }

    private void Focused(object sender, RoutedEventArgs e)
    {
            if(clearonce)
            {
                combobox1.Items.Clear();
                clearonce = false;
            }
            if (fillonce)
            {
              //fill the combobox items here 
                for (int i = 0; i < 10; i++)
                {
                    combobox1.Items.Insert(i, i);
                }
                fillonce = false;
            }           
    }
}

0

Creo una marca de agua como se menciona en esta publicación. funcionaría bien en este caso

Se necesita un poco de código, pero puede reutilizarlo para cualquier cuadro combinado o cuadro de texto (e incluso cuadros de contraseña), así que prefiero esta forma


0

Estoy usando una clase IsNullConverter en mi proyecto y funcionó para mí. aquí está el código en c #, cree una carpeta llamada Convertidor y agregue esta clase en esa carpeta, ya que el disparador utilizado no admite valor en lugar de nulo, y IsNullConverter simplemente haga eso

 public class IsNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("IsNullConverter can only be used OneWay.");
    }
}

agregue el espacio de nombres en el archivo xaml como este.

xmlns:Converters="clr-namespace:TymeSheet.Converter"

medio

xmlns:Converters="clr-namespace:YourProjectName.Converter"

use esta línea debajo de los recursos para que esté disponible a través del código xaml

<Converters:IsNullConverter x:Key="isNullConverter" />

aquí está el código xaml, utilicé aquí el disparador, por lo que cada vez que se selecciona un elemento en el cuadro combinado, la visibilidad de su texto se vuelve falsa.

<TextBlock Text="Select Project" IsHitTestVisible="False" FontFamily="/TimeSheet;component/Resources/#Open Sans" FontSize="14" Canvas.Right="191" Canvas.Top="22">
                        <TextBlock.Resources>
                            <Converters:IsNullConverter x:Key="isNullConverter"/>
                        </TextBlock.Resources>
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ElementName=ProjectComboBox,Path=SelectedItem,Converter={StaticResource isNullConverter}}" Value="False">
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>

0

// Código XAML

// Código de ViewModel

    private CategoryModel _SelectedCategory;
    public CategoryModel SelectedCategory
    {
        get { return _SelectedCategory; }
        set
        {
            _SelectedCategory = value;
            OnPropertyChanged("SelectedCategory");
        }
    }

    private ObservableCollection<CategoryModel> _Categories;
    public ObservableCollection<CategoryModel> Categories
    {
        get { return _Categories; }
        set
        {
            _Categories = value;
            _Categories.Insert(0, new CategoryModel()
            {
                CategoryId = 0,
                CategoryName = " -- Select Category -- "
            });
            SelectedCategory = _Categories[0];
            OnPropertyChanged("Categories");

        }
    }

0

Un poco tarde pero ...

Una forma más sencilla sería agregar un elemento de datos ficticios a la lista con el parámetro IsDummy = true y asegurarse de que no sea HitTestVisable y que su altura sea de 1 píxel (usando un convertidor) para que no se vea.

Que simplemente registrarse en SelectionChanged y en él, establezca el índice en el índice del elemento ficticio.

Funciona a las mil maravillas y de esta manera no se mete con el estilo y los colores del ComboBox o el tema de su aplicación.


0
InitializeComponent()
yourcombobox.text=" -- Select Team --";

El código anterior demuestra la forma más sencilla de lograrlo. Después de cargar la ventana, declare el texto del cuadro combinado, usando la propiedad .Text del cuadro combinado. Esto se puede extender a DatePicker, Textbox y otros controles también.


0

Lo hice antes de vincular el cuadro combinado con datos de la base de datos en código subyacente como este:

Combobox.Items.Add("-- Select Team --");
Combobox.SelectedIndex = 0;

1
Esto solo agrega el texto como una opción en el menú desplegable. Eso no era lo que pedía el OP.
Dean Friedland

se trata de agregar texto predeterminado y lo hice de esta manera
Atiq Baqi

0
  1. Coloque una etiqueta en la parte superior del cuadro combinado.

  2. Vincular el contenido de la etiqueta a la propiedad Text del cuadro combinado.

  3. Establezca la opacidad del cuadro combinado en cero, Opacidad = 0.

  4. Escribir texto predeterminado en la propiedad Text del cuadro combinado

          <ComboBox Name="cb"
            Text="--Select Team--" Opacity="0" 
            Height="40" Width="140" >
             <ComboBoxItem Content="Manchester United" />
             <ComboBoxItem Content="Lester" />
         </ComboBox>
     </Grid>

-2

Solo establezca el atributo IsEditable en verdadero

<ComboBox Name="comboBox1"            
          Text="--Select Team--"
          IsEditable="true"  <---- that's all!
          IsReadOnly="true"/>

-3

Sé que esto es semi viejo, pero ¿qué pasa de esta manera?

<DataTemplate x:Key="italComboWM">
    <TextBlock FontSize="11" FontFamily="Segoe UI" FontStyle="Italic" Text="--Select an item--" />
</DataTemplate>

<ComboBox EmptySelectionBoxTemplate="{StaticResource italComboWM}" />

2
ComboBoxno tiene EmptySelectionBoxTemplatepropiedad.
Novitchi S
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.