¿Cómo se puede hacer que un control deslizante WPF se ajuste solo a posiciones enteras discretas?

114

Con demasiada frecuencia quiero un control deslizante WPF que se comporte como el System.Windows.Forms.TrackBar de antaño. Es decir, quiero un control deslizante que vaya de X a Y pero que solo permita al usuario moverlo en posiciones enteras discretas.

¿Cómo se hace esto en WPF ya que la propiedad Value en el control deslizante es doble?

cplotts
fuente

Respuestas:

95

Si establece sus marcas de graduación de la manera correcta, puede usar IsSnapToTickEnabled . Esto funcionó bastante bien para mí. Consulte MSDN para obtener más detalles.

Brian Stewart
fuente
172

La respuesta simple es que aprovechas las propiedades IsSnapToTickEnabled y TickFrequency . Es decir, active el ajuste a tics y establezca la frecuencia de tick en 1.

O, en otras palabras ... aproveche los ticks ... pero no necesariamente tiene que mostrar los ticks a los que se está adaptando.

Consulte la siguiente pieza de xaml:

<Slider
    Orientation="Vertical"
    Height="200"
    Minimum="0"
    Maximum="10"
    Value="0"
    IsSnapToTickEnabled="True"
    TickFrequency="1"
/>
cplotts
fuente
1
Esta respuesta debería ser la aceptada. Funciona de maravilla. Gracias
Ashbay
Gracias @Ashbay ... en ese momento, quería darle crédito a alguien más por la respuesta ... en lugar de simplemente marcar mi propia respuesta como aceptada.
cplotts
Está en la sección Común del cuadro de diálogo Propiedades en el diseñador, pero en mi máquina, al menos, no estaba visible de inmediato porque la subsección Avanzada se contrajo y es demasiado fácil de pasar por alto.
amonroejj
46

Para aquellos que quieran ajustar a posiciones específicas , también puede usar la Tickspropiedad:

<Slider Minimum="1" Maximum="500" IsSnapToTickEnabled="True" Ticks="1,100,200,350,500" />
Dave
fuente
10

El truco rápido es útil pero tiene limitaciones, por ejemplo, si solo desea mostrar un subconjunto de ticks válidos. He tenido éxito con dos alternativas: enlazar a un número entero o redondear el nuevo valor. Aquí hay un ejemplo combinado:

public int MyProperty { get; set; }

private void slider1_ValueChanged(object sender,
    RoutedPropertyChangedEventArgs<double> e)
{
    (sender as Slider).Value = Math.Round(e.NewValue, 0);
}

<Slider
    Name="slider1"
    TickPlacement="TopLeft"
    AutoToolTipPlacement="BottomRight"
    ValueChanged="slider1_ValueChanged"
    Value="{Binding MyProperty}"
    Minimum="0" Maximum="100" SmallChange="1" LargeChange="10"
    Ticks="0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100"/>

No tengo idea de cómo se compara el rendimiento de ninguno de los dos con el truco rápido, pero no he tenido ningún problema *.

* Si también vincula el valor del control deslizante a un tipo de campo de texto, experimentará que, de vez en cuando, si usa el mouse, el campo de texto mostrará decimales. Si también se vincula a un int al mismo tiempo, la cadena vacía provocará que se lance una excepción de conversión que atasque brevemente la interfaz de usuario. Estos problemas no han sido lo suficientemente graves como para buscar soluciones.

mkjeldsen
fuente
Entonces, ¿esto permite que el usuario también tenga los otros valores en el control deslizante? ¿O todavía solo permite elegir el valor de los ticks? Una especie de pregunta extraña ... espero que entiendas lo que te estoy preguntando.
JLott
1
@JLott: Todavía puede ajustar solo a los Ticksvalores (0, 10, 20, ...) pero todos los valores intermedios (1, 2, ...) son válidos y se pueden seleccionar con, por ejemplo, las teclas de flecha.
mkjeldsen
Oh genial. No me di cuenta de que ... ¡Gracias!
JLott
Esto funciona para Silverlight donde no hay IsSnapToTickEnabledpropiedad.
ΩmegaMan