使用MVVMLight时出现“Thumb.DragStarted”事件问题

4
我正在尝试使用MVVMLight的EventToCommand触发Slider Thumb.DragStarted事件,但它不起作用。对于Slider事件ValueChanged,相同的事情完美地工作。
以下是我的代码:
<Slider
    Width="150"
    AutoToolTipPlacement="BottomRight"
    AutoToolTipPrecision="2"
    IsSnapToTickEnabled="True"
    Maximum="{Binding SilderMaxValue}"
    Minimum="0"
    Value="{Binding SliderValue}">                                        
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="ValueChanged">
                <cmd:EventToCommand
                    Command="{Binding SliderValueChangedCommand}"
                    PassEventArgsToCommand="True" />
             </i:EventTrigger>
        <i:EventTrigger EventName="Thumb.DragStarted">
                <cmd:EventToCommand
                    Command="{Binding SliderDragStartedCommand}"
                    PassEventArgsToCommand="True" />
        </i:EventTrigger>                                  
</Slider>

谢谢。

2个回答

5

当我试图做类似的事情时(尽管是使用Thumb.DragCompleted),我看到了您的帖子。无论如何,我使用了一个附加属性。如果有用,我会发布我的解决方案。


SliderDragBehavoirs.cs:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfApplication1
{
    public static class SliderDragBehaviors
    {
        public static readonly DependencyProperty DragCompletedCommandProperty =
            DependencyProperty.RegisterAttached("DragCompletedCommand", typeof(ICommand), typeof(SliderDragBehaviors),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(DragCompleted)));

        private static void DragCompleted(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var slider = (Slider)d;
            var thumb = GetThumbFromSlider(slider);

            thumb.DragCompleted += thumb_DragCompleted;
        }

        private static void thumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            FrameworkElement element = (FrameworkElement)sender;
            element.Dispatcher.Invoke(() =>
                {
                    var command = GetDragCompletedCommand(element);
                    var slider = FindParentControl<Slider>(element) as Slider;
                    command.Execute(slider.Value);
                });
        }

        public static void SetDragCompletedCommand(UIElement element, ICommand value)
        {
            element.SetValue(DragCompletedCommandProperty, value);
        }

        public static ICommand GetDragCompletedCommand(FrameworkElement element)
        {
            var slider = FindParentControl<Slider>(element);
            return (ICommand)slider.GetValue(DragCompletedCommandProperty);
        }

        private static Thumb GetThumbFromSlider(Slider slider)
        {
            var track = slider.Template.FindName("PART_Track", slider) as Track;
            return track == null ? null : track.Thumb;
        }

        private static DependencyObject FindParentControl<T>(DependencyObject control)
        {
            var parent = VisualTreeHelper.GetParent(control);
            while (parent != null && !(parent is T))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }
            return parent;
        }
    }
}

这里有几个值得注意的事情。因为命令被连接到Slider,但事件在Thumb上触发,所以需要能够查找可视树以便从一个控件获取另一个控件。


XAML示例:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:behaviors="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">

    <Grid x:Name="grid">
        <Slider behaviors:SliderDragBehaviors.DragCompletedCommand="{Binding Path=DragCompletedCommand}"/>
    </Grid>
</Window>

希望这对你有所帮助 :)

1

我在使用Tom Allen的代码时遇到了问题,因为当我想将其与命令绑定时,滑块模板不可用。基本上,我只需要等待滑块控件加载完成,然后再尝试一次即可。 以下是我需要进行的更改,以使其正常工作:

    private static void DragCompleted(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //the Template of the slider is not available now
        //we have to wait for the slider to load completely in order to do this
        var slider = (Slider)d;
        slider.Loaded += slider_Loaded;
    }

    static void slider_Loaded(object sender, RoutedEventArgs e)
    {
        var slider = (Slider)sender;
        var thumb = GetThumbFromSlider(slider);
        thumb.DragCompleted += thumb_DragCompleted;
    }

希望能有所帮助! 敬礼

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接