J'ai ismovétopoindenabled sur votre curseur, donc lorsque je clique sur n'importe où sur le composant, le sélecteur se déplace vers ma souris. Le problème est que si j'ai cette option et cliquez sur la souris enfoncée pour faire glisser le sélecteur, le sélecteur ne bouge pas. Quelqu'un sait comment résoudre ce problème? P>
6 Réponses :
Le moyen le plus simple est du curseur de sous-classe: auquel cas votre xaml serait: p> pour une solution plus polyvalente qui ne sousclure pas le curseur de sous-classement que vous pouvez le faire avec une propriété attachée: p> Vous utiliseriez cette propriété connectée sur le curseur avec la propriété ismovétopoindSensible: p> <Slider IsMoveToPointEnabled="True" my:SliderTools.MoveToPointOnDrag="True" ... />
Merci Ray! Je pense que je l'ai presque travaillé. Je dispose d'un problème avec Type Casting dans la fonction de déplacement de la souris dans SliderTools. Voici mon erreur: impossible de lancer l'objet de type 'system.windowows.input.mousebuttoneventhandler' to tapez 'system.windows.input.mouseeventhandler'. Des pensées sur la façon de le réparer?
Désolé pour ça. Pour la technique d'événement routé, je devais passer dans un MouseButTonventargs au lieu d'un MouseeEventargs car les Mouseevenargs vérifient en réalité son type d'événement. J'ai apporté le changement nécessaire et j'ai testé le code résultant. Il semble faire exactement ce que vous voulez. Prendre plaisir!
Agréable! Cependant, si vous cliquez à l'extérieur du curseur et faites-la glisser, une traînée est toujours initiée. Si vous avez deux curseurs proches les uns des autres, cela provoque parfois une modification non intentionnelle à une.
Que diriez-vous de
private void slider_PreviewMouseDown(object sender, MouseButtonEventArgs e) { Point point = e.GetPosition(slider); slider.Value = point.X; }
Inspiré par Ray Burns Réponse, la manière la plus simple que j'ai trouvée est la suivante: avec MySlider étant le nom de mon curseur. P> Il y a deux problèmes avec Cette solution (et la plupart des autres dans ce sujet): Voici une version améliorée, qui s'attaque à la fois aux deux problèmes: P>
1. Si vous cliquez et maintenez la souris située à l'extérieur du curseur, puis déplacez-la sur le curseur, la traînée commencera.
2. Si vous utilisez le curseur Autotooltip, il ne fonctionnera pas lors de la glissant avec cette méthode. P> mySlider.MouseMove += (sender, args) =>
{
if (args.LeftButton == MouseButtonState.Pressed && this.clickedInSlider)
{
var thumb = (mySlider.Template.FindName("PART_Track", mySlider) as System.Windows.Controls.Primitives.Track).Thumb;
thumb.RaiseEvent(new MouseButtonEventArgs(args.MouseDevice, args.Timestamp, MouseButton.Left)
{
RoutedEvent = UIElement.MouseLeftButtonDownEvent,
Source = args.Source
});
}
};
mySlider.AddHandler(UIElement.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler((sender, args) =>
{
clickedInSlider = true;
}), true);
mySlider.AddHandler(UIElement.PreviewMouseLeftButtonUpEvent, new RoutedEventHandler((sender, args) =>
{
clickedInSlider = false;
}), true);
Meilleure version que j'ai trouvée jusqu'à présent pour un curseur amélioré. Je l'utilise pour créer un curseur plus convivial de touche. Je l'ai trouvé plus propre à la mettre en œuvre dans une sous-classe cependant. Merci!
Vous avez besoin de curseur personnalisé et de tact personnalisé. Lorsque vous cliquez sur Slider (pas sur le pouce) - P>
Vous pouvez appeler dans la méthode du curseur personnalisé, appelant à l'intérieur OnmouseleftButToundown (MouseButToneventargs e) Code> P>
OnmouseleftButTondown (MouseButToneventargs e) Code> Li>
ol> ol>
Voici la version améliorée de la réponse de @ Timpohlmann.
Celui-ci relève Il n'y a pas non plus besoin de variable d'assistance. P> Ceci est mis en œuvre comme comportement. xaml: p> comportement: p> MouseButToneVenthandler code> une seule fois. Bien que le pouce lève
dragdeltaeventhandler code> en interne à chaque mouvement de la souris. Mais j'ai trouvé inutile d'incendier
MouseleftbutondownEvent code> sur le pouce à chaque mouvement de la souris moi-même. p>
associéObject code> est le curseur que ce comportement est attaché à. p>
public sealed class FreeSlideBehavior : Behavior<Slider>
{
private Thumb _thumb;
private Thumb Thumb
{
get
{
if (_thumb == null)
{
_thumb = ((Track)AssociatedObject.Template.FindName("PART_Track", AssociatedObject)).Thumb;
}
return _thumb;
}
}
protected override void OnAttached()
{
AssociatedObject.MouseMove += OnMouseMove;
}
protected override void OnDetaching()
{
AssociatedObject.MouseMove -= OnMouseMove;
}
private void OnMouseMove(object sender, MouseEventArgs args)
{
if (args.LeftButton == MouseButtonState.Released) return;
if(Thumb.IsDragging) return;
if (!Thumb.IsMouseOver) return;
Thumb.RaiseEvent(new MouseButtonEventArgs(args.MouseDevice, args.Timestamp, MouseButton.Left)
{
RoutedEvent = UIElement.MouseLeftButtonDownEvent
});
}
}
Notez que vous devez ajouter l'ensemble "Interactivité" pour que cela fonctionne, ce qui n'est pas inclus par défaut.
Aussi, apparemment en utilisant le comportement casse le concepteur ( Connect.Microsoft.com/visualstudio/feedback/Détails/755407/ ... , CatelProject.atlassian.net/browse/ctl-765 ). Je pense que je vais l'éviter ...
Reliure à un événement de déplacement de la souris Se sentir vraiment faux pour moi - je voulais un clic sur le curseur pour agir comme un clic sur le pouce de sorte que l'événement ne tire que une fois et déclenche un comportement glissant normal. Après avoir fait des creuser, j'ai proposé une solution alternative qui fonctionne.
Le curseur OnpreviewMousEftButTondown code> Ce qui permet de changer la valeur du curseur lorsque
ismovetopoindenabled code> est
vrai code>. Cependant, la méthode
OnmouseleftButTondown code> est ce que les poignées se concentrent sur la mise au point, capturant la souris, puis éliminant l'événement
dragstarté code>. La stratégie que j'ai prise est d'avoir le
PreviewMousEftButTondown code> sur le curseur déclencher manuellement le
Mouseleftbuttonown code> sur le pouce: p>
mySlider.AddHandler(
PreviewMouseLeftButtonDownEvent,
new MouseButtonEventHandler((sender, e) =>
{
Track track = mySlider.Template.FindName("PART_Track", mySlider) as Track;
// It's important to check `track.Thumb.IsMouseOver`, because if it's `true` then
// the Thumb will already have its `OnMouseLeftButtonDown` method called - there's
// no need for us to manually trigger it (and doing so would result in firing the
// event twice, which is bad).
if (!mySlider.IsMoveToPointEnabled || track == null || track.Thumb == null || track.Thumb.IsMouseOver)
{
return;
}
// When `IsMoveToPointEnabled` is true, the Slider's `OnPreviewMouseLeftButtonDown`
// method updates the slider's value to where the user clicked. However, the Thumb
// hasn't had its position updated yet to reflect the change. As a result, we must
// call `UpdateLayout` on the Thumb to make sure its position is correct before we
// trigger a `MouseLeftButtonDownEvent` on it.
track.Thumb.UpdateLayout();
track.Thumb.RaiseEvent(new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left)
{
RoutedEvent = MouseLeftButtonDownEvent,
Source = track.Thumb
});
}),
true);
Cela a fonctionné pour moi, et voici la version nettoyée et plus facile à coller: Pastebin.com/4yrjsqag juste appeler que dans votre constructeur de fenêtre principal, ou quelque chose et renommez "HuespectrumsLider" à votre curseur.