Comment faire en sorte qu'un curseur WPF s'aligne uniquement sur des positions entières discrètes?

114

Trop souvent, je veux un curseur WPF qui se comporte comme l'ancien System.Windows.Forms.TrackBar. Autrement dit, je veux un curseur qui va de X à Y mais qui permet uniquement à l'utilisateur de le déplacer dans des positions entières discrètes.

Comment faire cela dans WPF puisque la propriété Value sur le Slider est double?

cplotts
la source

Réponses:

95

Si vous définissez vos graduations de la bonne manière, vous pouvez utiliser IsSnapToTickEnabled . Cela a plutôt bien fonctionné pour moi. Consultez MSDN pour plus de détails.

Brian Stewart
la source
172

La réponse simple est que vous tirez parti des propriétés IsSnapToTickEnabled et TickFrequency . Autrement dit, activez l'alignement sur les graduations et réglez la fréquence de graduation sur 1.

Ou, en d'autres termes ... tirez parti des tiques ... mais vous n'avez pas nécessairement à montrer les tiques sur lesquelles vous vous accrochez.

Découvrez le morceau suivant de xaml:

<Slider
    Orientation="Vertical"
    Height="200"
    Minimum="0"
    Maximum="10"
    Value="0"
    IsSnapToTickEnabled="True"
    TickFrequency="1"
/>
cplotts
la source
1
Cette réponse devrait être celle acceptée. Fonctionne comme un charme. Merci
Ashbay
Merci @Ashbay ... à l'époque, je voulais donner à quelqu'un d'autre crédit pour la réponse ... plutôt que de simplement marquer ma propre réponse comme acceptée.
cplotts du
C'est sous la section commune de la boîte de dialogue Propriétés dans le concepteur, mais sur ma machine, au moins, elle n'était pas immédiatement visible car la sous-section Avancé était réduite et trop facile à ignorer.
amonroejj
46

Pour ceux qui souhaitent s'aligner sur des positions spécifiques , vous pouvez également utiliser la Tickspropriété:

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

L'astuce d'accrochage est pratique mais présente des limites, par exemple si vous souhaitez afficher uniquement un sous-ensemble de graduations valides. J'ai eu du succès avec deux alternatives: soit lier à un entier, soit arrondir la nouvelle valeur. Voici un exemple combiné:

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"/>

Je n'ai aucune idée de comment la performance de l'un ou l'autre se compare à l'astuce instantanée mais je n'ai eu aucun problème *.

* Si vous liez également la valeur du curseur à un type de champ de texte, vous constaterez que, de temps en temps si vous utilisez la souris, le champ de texte affichera des décimales. Si vous vous liez également à un int en même temps, la chaîne vide provoquera la levée d'une exception de conversion qui embourbera brièvement l'interface utilisateur. Ces problèmes n'ont pas été suffisamment graves pour que je recherche des solutions.

mkjeldsen
la source
Cela permet-il à l'utilisateur d'avoir également les autres valeurs sur le curseur? Ou cela ne permet-il toujours que de choisir la valeur des graduations. Une sorte de question étrange ... j'espère que vous comprenez ce que je demande.
JLott
1
@JLott: Vous ne pouvez toujours accrocher que les Ticksvaleurs (0, 10, 20, ...) mais toutes les valeurs intermédiaires (1, 2, ...) sont valides et peuvent être sélectionnées avec par exemple les touches fléchées.
mkjeldsen
Oh bien. Je n'avais pas réalisé ça ... Merci!
JLott
Cela fonctionne pour Silverlight où il n'y a pas de IsSnapToTickEnabledpropriété.
ΩmegaMan