我为我的Slider启用了IsMoveToPointEnabled,所以当我单击组件上的任何位置时,选择器会移动到我的鼠标.问题是如果我打开此选项并单击并按住鼠标以拖动选择器,选择器不会移动.有人知道怎么修这个东西吗?
Ray*_*rns 18
最简单的方法是子类Slider:
public class CustomSlider : Slider
{
public override void OnPreviewMouseMove(MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed)
OnPreviewMouseLeftButtonDown(e);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您的XAML将是:
<my:CustomSlider IsMoveToPointEnabled="True" />
Run Code Online (Sandbox Code Playgroud)
对于不是Slider子类的更通用的解决方案,您可以使用附加属性来执行此操作:
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,
});
};
}
});
}
Run Code Online (Sandbox Code Playgroud)
您可以在Slider上使用此附加属性以及IsMoveToPointEnabled属性:
<Slider IsMoveToPointEnabled="True" my:SliderTools.MoveToPointOnDrag="True" ... />
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都可以通过在左键按下时将PreviewMouseMove事件转换为等效的PreviewMouseLeftButtonDown事件来工作.
请注意,当属性设置为false时,附加属性不会删除事件处理程序.我这样写是为了简单,因为你几乎从不需要删除这样的处理程序.我建议您坚持使用这个简单的解决方案,但是如果您愿意,可以修改PropertyChangedCallback以在NewValue为false时删除处理程序.
灵感来自Ray Burns答案,我找到的最简单的方法是:
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
});
}
};
Run Code Online (Sandbox Code Playgroud)
mySlider是我的Slider的名字.
此解决方案存在两个问题(本主题中的大多数其他问题):
1.如果单击并按住滑块外的鼠标,然后在滑块上移动它,则会开始拖动.
2.如果您使用滑块的自动工具提示,则使用此方法拖动时无效.
所以这是一个改进的版本,解决了这两个问题:
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);
Run Code Online (Sandbox Code Playgroud)
clickedInSlider是在类中定义的私有辅助变量.
通过使用clickedInSlider辅助变量我们避免1.处理PreviewMouseButtonDown事件(因为MoveToPoint = true),所以我们必须使用mySlider.AddHandler.
通过在Thumb上而不是Slider上引发事件,我们确保显示autotooltip.
| 归档时间: |
|
| 查看次数: |
5993 次 |
| 最近记录: |