我想将Slider的值更改为鼠标滚轮:当我向上滚动时,Slider'sValue属性应该增加,当我向下滚动时,它应该减少。行为应该独立于鼠标位置或当前焦点。解决方案最好使用绑定并且仅是XAML,但代码隐藏解决方案也足够了。
Slider
Slider's
Value
olqngx591#
您可以使用一个附加的行为,将父Window的PreviewMouseWheel事件挂接起来,并设置Slider的值。使用附加行为使您能够封装功能并将其重用于任何Slider控件,而无需修改每个视图的代码隐藏文件。这里有一个例子供你参考。
Window
PreviewMouseWheel
public class MouseWheelBehavior { public static double GetValue(Slider slider) { return (double)slider.GetValue(ValueProperty); } public static void SetValue(Slider slider, double value) { slider.SetValue(ValueProperty, value); } public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached( "Value", typeof(double), typeof(MouseWheelBehavior), new UIPropertyMetadata(0.0, OnValueChanged)); public static Slider GetSlider(UIElement parentElement) { return (Slider)parentElement.GetValue(SliderProperty); } public static void SetSlider(UIElement parentElement, Slider value) { parentElement.SetValue(SliderProperty, value); } public static readonly DependencyProperty SliderProperty = DependencyProperty.RegisterAttached( "Slider", typeof(Slider), typeof(MouseWheelBehavior)); private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Slider slider = d as Slider; slider.Loaded += (ss, ee) => { Window window = Window.GetWindow(slider); if (window != null) { SetSlider(window, slider); window.PreviewMouseWheel += Window_PreviewMouseWheel; } }; slider.Unloaded += (ss, ee) => { Window window = Window.GetWindow(slider); if(window != null) { SetSlider(window, null); window.PreviewMouseWheel -= Window_PreviewMouseWheel; } }; } private static void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { Window window = sender as Window; Slider slider = GetSlider(window); double value = GetValue(slider); if(slider != null && value != 0) { slider.Value += slider.SmallChange * e.Delta / value; } } }
使用方法:
<Slider local:MouseWheelBehavior.Value="120" />
k2arahey2#
我找不到使用绑定或XAML的方法,但这个相当简单的代码隐藏解决方案可以工作:
MyPanel.PreviewMouseWheel += (sender, e) => MySlider.Value += MySlider.SmallChange * e.Delta / 120;
一些注意事项:
MyPanel
Control
MouseWheel
ScrollViewer
Delta
120
MySlider.Value
doinxwow3#
虽然accepted answer * 确实 * 工作,但它有一些严重的缺点,使其在我的情况下无法使用:
另一种没有这些问题的方法是使用官方的Microsoft.Xaml.Behaviors.Wpf nuget包:
Microsoft.Xaml.Behaviors.Wpf
public class MouseWheelSliderBehavior : Behavior<Slider> { public double Amount { get => (double)GetValue(AmountProperty); set => SetValue(AmountProperty, value); } public static readonly DependencyProperty AmountProperty = DependencyProperty.RegisterAttached( nameof(Amount), typeof(double), typeof(MouseWheelSliderBehavior), new UIPropertyMetadata(0.0)); private void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { if (Amount == 0.0) return; Slider slider = (Slider)sender; if (e.Delta > 0) { slider.Value += Amount; } else { slider.Value -= Amount; } } protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.PreviewMouseWheel += this.AssociatedObject_PreviewMouseWheel; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.PreviewMouseWheel -= this.AssociatedObject_PreviewMouseWheel; } }
添加以下命名空间:
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
然后,使用行为:
<Slider> <i:Interaction.Behaviors> <local:MouseWheelSliderBehavior Amount="1" /> </i:Interaction.Behaviors> </Slider>
无论您将Amount设置为什么,都是滑块值将改变的量。
Amount
3条答案
按热度按时间olqngx591#
您可以使用一个附加的行为,将父
Window
的PreviewMouseWheel
事件挂接起来,并设置Slider
的值。使用附加行为使您能够封装功能并将其重用于任何
Slider
控件,而无需修改每个视图的代码隐藏文件。这里有一个例子供你参考。
使用方法:
k2arahey2#
我找不到使用绑定或XAML的方法,但这个相当简单的代码隐藏解决方案可以工作:
一些注意事项:
MyPanel
可以是任何Control
。当鼠标在使用滚轮时位于此Control
上方时,将触发该事件。MouseWheel
或PreviewMouseWheel
事件。如果有其他控件处理MouseWheel
事件(如ScrollViewer
),则后者更方便。Delta
将保持值120
。所以你必须除以这个值才能得到预期的行为。MySlider.Value
绑定到代码中的某个属性,则应调整该属性的值,而不是直接更改Slider
。doinxwow3#
虽然accepted answer * 确实 * 工作,但它有一些严重的缺点,使其在我的情况下无法使用:
Slider
控件(以最后创建的为准)另一种没有这些问题的方法是使用官方的
Microsoft.Xaml.Behaviors.Wpf
nuget包:C#
XAML
添加以下命名空间:
然后,使用行为:
无论您将
Amount
设置为什么,都是滑块值将改变的量。