12
votes

Le curseur ne glisse pas en combinaison avec un comportement ismovétopoind

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?


0 commentaires

6 Réponses :


18
votes

Le moyen le plus simple est du curseur de sous-classe: xxx pré>

auquel cas votre xaml serait: p> xxx pré>

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> xxx pré>

Vous utiliseriez cette propriété connectée sur le curseur avec la propriété ismovétopoindSensible: p>

<Slider IsMoveToPointEnabled="True" my:SliderTools.MoveToPointOnDrag="True" ... />


3 commentaires

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.



0
votes

Que diriez-vous de

    private void slider_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        Point point = e.GetPosition(slider);
        slider.Value = point.X;
    }


0 commentaires

7
votes

Inspiré par Ray Burns Réponse, la manière la plus simple que j'ai trouvée est la suivante: xxx pré>

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):
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>

Voici une version améliorée, qui s'attaque à la fois aux deux problèmes: 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);


1 commentaires

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!



0
votes
  1. Vous avez besoin de curseur personnalisé et de tact personnalisé. Lorsque vous cliquez sur Slider (pas sur le pouce) - XXX

    Vous pouvez appeler dans la méthode du curseur personnalisé, appelant à l'intérieur OnmouseleftButToundown (MouseButToneventargs e)

    1. Vous pouvez éteindre le pouce et utiliser la Réflaction pour appeler OnmouseleftButTondown (MouseButToneventargs e)

0 commentaires

1
votes

Voici la version améliorée de la réponse de @ Timpohlmann.

Celui-ci relève 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>

Il n'y a pas non plus besoin de variable d'assistance. P>

Ceci est mis en œuvre comme comportement. associéObject code> est le curseur que ce comportement est attaché à. p>

xaml: p> xxx pré>

comportement: 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
        });
    }
}


2 commentaires

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 ...



1
votes

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);


1 commentaires

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.