web-dev-qa-db-fra.com

Comment créer un accrochage de curseur WPF uniquement sur des positions entières discrètes?

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

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

106
cplotts

Si vous cochez correctement les graduations, vous pouvez utiliser IsSnapToTickEnabled . Cela a plutôt bien fonctionné pour moi. Voir MSDN pour plus de détails.

90
Brian Stewart

La réponse simple est que vous tirez parti des propriétés IsSnapToTickEnabled et TickFrequency. En d’autres termes, activez l’accrochage sur les ticks et réglez la fréquence de ticks sur 1.

Ou, en d'autres termes ... tirez parti des ticks ... mais vous n'avez pas nécessairement à montrer les ticks pour lesquels vous vous adaptez.

Découvrez le morceau de xaml suivant:

<Slider
    Orientation="Vertical"
    Height="200"
    Minimum="0"
    Maximum="10"
    Value="0"
    IsSnapToTickEnabled="True"
    TickFrequency="1"
/>
160
cplotts

Pour ceux qui souhaitent se caler sur des positions spécifiques, vous pouvez également utiliser la propriété Ticks:

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

L'astuce de capture est pratique mais présente des limites, par exemple si vous souhaitez afficher uniquement un sous-ensemble de ticks 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 la façon dont la performance de l'un ou de l'autre se compare à celle du jeu instantané, mais je n'ai eu aucun problème *.

* Si vous aussi liez 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 affiche 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 perturbera brièvement l'interface utilisateur. Ces problèmes ne sont pas suffisamment graves pour que je recherche des solutions.

9
mkjeldsen