Tengo IsMoveToPoint habilitado para mi control deslizante, por lo que cuando hago clic en cualquier parte del componente, el selector se mueve al mouse. El problema es si tengo esta opción activada y hago clic y mantengo presionado el botón del mouse hacia abajo para arrastrar el selector; el selector no se mueve. ¿Alguien sabe cómo arreglar esto?El control deslizante no se arrastra en combinación con el comportamiento IsMoveToPointEnabled
Respuesta
La forma más sencilla es la subclase deslizante:
public class CustomSlider : Slider
{
public override void OnPreviewMouseMove(MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed)
OnPreviewMouseLeftButtonDown(e);
}
}
En cuyo caso su XAML sería:
<my:CustomSlider IsMoveToPointEnabled="True" />
Para una solución más versátil que no subclase deslizante que puede hacerlo con una propiedad adjunta:
public class SliderTools : DependencyObject
{
public static bool GetMoveToPointOnDrag(DependencyObject obj) { return (bool)obj.GetValue(MoveToPointOnDragProperty); }
public static void SetMoveToPointOnDrag(DependencyObject obj, bool value) { obj.SetValue(MoveToPointOnDragProperty, value); }
public static readonly DependencyProperty MoveToPointOnDragProperty = DependencyProperty.RegisterAttached("MoveToPointOnDrag", typeof(bool), typeof(SliderTools), new PropertyMetadata
{
PropertyChangedCallback = (obj, changeEvent) =>
{
var slider = (Slider)obj;
if((bool)changeEvent.NewValue)
slider.MouseMove += (obj2, mouseEvent) =>
{
if(mouseEvent.LeftButton == MouseButtonState.Pressed)
slider.RaiseEvent(new MouseButtonEventArgs(mouseEvent.MouseDevice, mouseEvent.Timestamp, MouseButton.Left)
{
RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
Source = mouseEvent.Source,
});
};
}
});
}
Utilizaría esta propiedad adjunta en el control deslizante junto con el IsMov eToPointEnabled propiedad:
<Slider IsMoveToPointEnabled="True" my:SliderTools.MoveToPointOnDrag="True" ... />
Ambas soluciones de trabajo mediante la conversión de los eventos en los eventos PreviewMouseMove PreviewMouseLeftButtonDown equivalentes siempre que el botón izquierdo está abajo.
Tenga en cuenta que la propiedad adjunta no elimina el controlador de eventos cuando la propiedad se establece en falso. Lo escribí de esta manera por simplicidad, ya que casi nunca necesitarías eliminar dicho controlador. Le recomiendo que se quede con esta solución simple, pero si lo desea, puede modificar PropertyChangedCallback para eliminar el controlador cuando NewValue sea falso.
¿Qué tal
private void slider_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(slider);
slider.Value = point.X;
}
Inspirado por Ray quemaduras respuesta, la forma más sencilla que he encontrado es la siguiente:
mySlider.PreviewMouseMove += (sender, args) =>
{
if (args.LeftButton == MouseButtonState.Pressed)
{
mySlider.RaiseEvent(new MouseButtonEventArgs(args.MouseDevice, args.Timestamp, MouseButton.Left)
{
RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
Source = args.Source
});
}
};
Con mySlider ser el nombre de mi Slider.
Hay dos problemas con esta solución (y la mayoría de los demás en este tema):
1. Si hace clic y mantiene el mouse fuera del control deslizante y lo mueve en el control deslizante, se iniciará la acción de arrastre.
2. Si está utilizando la sugerencia de autolín del control deslizante, no funcionará mientras arrastra con este método.
Así que aquí es una versión mejorada, que fuerza a ambos problemas:
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);
clickedInSlider es una variable auxiliar privado definido somwhere en la clase.
Al usar la variable de ayuda clickedInSlider evitamos 1. Se maneja el evento PreviewMouseButtonDown (debido a MoveToPoint = true), por lo que tenemos que usar mySlider.AddHandler.
Al mostrar el evento en el pulgar en lugar del control deslizante, nos aseguramos de que aparece la sugerencia de autotool.
Mejor versión que he encontrado hasta ahora para un control deslizante mejorado. Lo uso para crear un control deslizante más táctil. Sin embargo, me pareció más limpio implementarlo en una subclase. ¡Gracias! – monoceres
Necesita control deslizante personalizado y pulgar personalizado.Al hacer clic en el control deslizante (no un golpe en el pulgar) -
var hitTestResult = VisualTreeHelper.HitTest(this, point); if (hitTestResult == null) return; var parent = hitTestResult.VisualHit.ParentOfType<Thumb>(); if (parent != null) return; _customThumb.OnMouseLeftButtonDown(e);
puede llamar en el método deslizador personalizada, que llame dentro OnMouseLeftButtonDown(MouseButtonEventArgs e)
- Puede usted standart Thumb y use Reflaction para llamar a
OnMouseLeftButtonDown(MouseButtonEventArgs e)
Aquí está la versión mejorada de la respuesta de @ TimPohlmann.
éste plantea MouseButtonEventHandler
sólo una vez. aunque el pulgar aumenta DragDeltaEventHandler
internamente en cada movimiento del mouse. pero me pareció innecesario disparar MouseLeftButtonDownEvent
en el pulgar en cada movimiento del mouse yo mismo.
Además, no hay necesidad de que la variable auxiliar.
Esto se implementa como un comportamiento. AssociatedObject
es el control deslizante al que se asocia este comportamiento.
XAML:
<Slider ...>
<i:Interaction.Behaviors>
<slid:FreeSlideBehavior />
</i:Interaction.Behaviors>
</Slider>
Comportamiento:
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
});
}
}
Tenga en cuenta que necesita agregar el ensamblado "Interactividad" para que esto funcione, que no está incluido por defecto. –
Además, al parecer utilizando Comportamiento rompe el diseñador (https://connect.microsoft.com/VisualStudio/feedback/details/755407/xaml-designer-will-not-display-when-using-blend-sdk-behaviors, https: //catelproject.atlassian.net/browse/CTL-765). Creo que lo evitaré ... –
- 1. control deslizante jquery con valor superior que se desplaza con el control deslizante
- 2. Buttondownfcn no funciona en el control deslizante
- 3. En MATLAB, ¿cómo se puede ejecutar una devolución de llamada mientras se arrastra un control deslizante?
- 4. jQuery - Usar .one() con el control deslizante
- 5. Usando delegate() con el control deslizante()?
- 6. ¿Cómo detener el valor de actualización del control deslizante mientras lo arrastra?
- 7. : el control deslizante no funciona correctamente en IE9
- 8. ¿Se puede mover el control deslizante en selenio?
- 9. Control deslizante con intervalos múltiples
- 10. Actualización de DIV con contenido XML en el control deslizante
- 11. Control deslizante para el volumen - JQuery/Javascript
- 12. Cómo probar el control deslizante jQuery UI con Selenium IDE?
- 13. Cómo evitar que el control deslizante jQuery UI se superponga?
- 14. Después de cambiar css, el control deslizante no funciona
- 15. as3 controla el volumen del micrófono con un control deslizante?
- 16. JQuery UI Control deslizante con pasos no lineales/exponenciales/logarítmicos
- 17. Raphael.js arrastra con escala provoca un comportamiento de salto extraño
- 18. Comportamiento del paso deslizante de MATLAB
- 19. Control deslizante logarítmico en Mathematica
- 20. Barra lateral oculta que aparece en el control deslizante
- 21. Personalizar un control deslizante
- 22. Control deslizante Twin .net
- 23. jQuery UI Control deslizante con botones de control?
- 24. Control deslizante en mi PreferenceScreen
- 25. Matplotlib: gráfico de contorno con control deslizante
- 26. Quitar resaltado en el control deslizante de jQuery
- 27. Jquery UI: control deslizante de rango. ¿Qué control deslizante se mueven?
- 28. El rango del control deslizante Jquery no funciona en el iPad
- 29. ocultando el cuadro de entrada del control deslizante en jquery
- 30. Comportamiento extraño del depurador cuando se utiliza el control #line
Gracias Ray! Creo que casi lo tengo funcionando. Tengo un problema con el tipo de conversión en la función de movimiento del mouse en SliderTools. Aquí está mi error: No se puede convertir objeto de tipo 'System.Windows.Input.MouseButtonEventHandler' al tipo 'System.Windows.Input.MouseEventHandler'. ¿Alguna idea sobre cómo solucionarlo? –
Perdón por eso. Para la técnica de evento enrutado, necesitaba pasar un MouseButtonEventArgs en lugar de un MouseEventArgs porque MouseEventArgs en realidad comprueba su tipo de evento. Realicé el cambio necesario y probé el código resultante. Parece hacer exactamente lo que quieres. ¡Disfrutar! –