4

在我的应用程序中,我使用两个滑块来控制某些图像的亮度和对比度,并且当两个滑块中的任何一个更改其值属性时,每次都必须逐个像素地完全重新计算图像。较小图像的重新计算完全正常,不会导致任何问题,但是,较大的图像需要更长的时间重新计算,并且与鼠标指针相比,滑块的移动会稍有延迟。我确实需要或多或少地实时重新计算图像,因此仅仅有一个事件DragCompleted或类似的事件是不可接受的。

ValueChanged使用滑块的 -event初始化重新计算。我认为这个问题的一个很好的解决方案是如果事件没有尽快触发,但至少要等 50 毫秒才能再次触发,但是是否有滑块的属性可以控制它?

我正在考虑的另一个解决方案是在事件被处理时从滑块中删除事件,并在短时间内再次添加它,但这可能会导致一些延迟,这在此处也不是首选。

我在任何地方都找不到关于这个主题的任何东西,所以如果有人有任何好的建议或方向我可以使用,我会非常感激。

4

4 回答 4

6

您还可以使用WPF 4.5 中引入的BindingBase.Delay 属性。

只需将 Slider 的值绑定到绑定上的依赖属性设置Delay。这将仅在特定时间(例如 500 毫秒)后导致值更新,这可以使您的应用程序更流畅。

于 2014-08-08T12:58:11.200 回答
4

如果您认为您的应用程序不需要在每次 触发ValueChanged事件时进行计算,您可以使用 Thumb 控件中的DragCompleted事件来确定用户拖动完控件后的位置。

<Slider Thumb.DragCompleted="Slider_DragCompleted_1"  
    Height="27" Margin="132,162,0,0" VerticalAlignment="Top" Width="303"/>

当用户停止拖动时,

private void Slider_DragCompleted_1(object sender, DragCompletedEventArgs e)
{
    Slider s = sender as Slider;
    // Your code
    MessageBox.Show(s.Value.ToString());
}

但请注意,这仅在用户拖动滑块时有效。当用户单击滑块时不会触发。

请参阅this以处理其他事件,例如鼠标单击等。

如果你想计算一些时间延迟,那么你可以使用计时器。

编辑: 根据您的要求,您可以这样做。在“ValueChanged”事件中。

 // Start a new thread only if the thread is stopped 
 // or the thread has not been created yet.
 if (threadPopular == null || threadPopular.ThreadState == ThreadState.Stopped)
 {
           threadPopular = new Thread(new ThreadStart(Your function));
           threadPopular.Start();
  }
于 2013-08-29T12:50:44.813 回答
0

我可以使用将异步Backgroundworker完成图像处理的地方来实现这一点。Backgroundworker

另外,我建议您可以Timer在此处使用并将其滴答时间设置为舒适的值。在每个 sliderchanged 事件上,如果未启用,则启动计时器。在计时器滴答事件处理程序中,您可以检查后台工作人员是否正在工作,然后您可以取消先前的操作并将新操作放在上面。在 bacgroundworkerdone 事件处理程序中,只需停止计时器。

谢谢

于 2013-08-29T12:42:37.697 回答
0

虽然您可以使用 BindingBase.Delay,但这会导致延迟,即使需要进行一次更改也是如此。另一种方法可能是在 Slider Value 中使用OneWay绑定并使用如下异步命令:

XAML 代码:

<Slider Value="{Binding MyValue, Mode=OneWay}">
    <i:Interaction.Triggers>
     <i:EventTrigger EventName="ValueChanged">
        <mvvmlight:EventToCommand 
        Command="{Binding SetValueCommand, Mode=OneWay}"
        EventArgsConverter="{StaticResource 
        RoutedPropertyChangedEventArgsToDoubleConverter}"
        PassEventArgsToCommand="True" />
        </i:EventTrigger>
     </i:Interaction.Triggers>

值转换器:

using GalaSoft.MvvmLight.Command;

    public class RoutedPropertyChangedEventArgsToDoubleConverter : IEventArgsConverter
    {
        public object Convert(object value, object parameter)
        {
            var args = (RoutedPropertyChangedEventArgs<double>)value;
            var element = (FrameworkElement)parameter;

            return args.NewValue;
        }
    }

以及命令的回调:

    double _updateVal;
    Task _delay;

    private async void SetValue(double val)
    {            
        if (_delay != null)
        {
            // in case of high frequency updates, most updates will return here
            _updateVal = val; 
            return;
        }

        // only the first update reaches here

        // caluclate the image here 
        MyValue = val; // update slider

        _delay = Task.Delay(500);
        await _delay;

        // in case there are pending updates:
        while (_updateVal.HasValue)
        {
            // caluclate the image here 
            MyValue = _updateVal.Value; // update slider

            _updateVal = null;

            _delay = Task.Delay(500);
            await _delay;
        }

        _delay = null;

    }

这样,您只能减少图像计算的频率,而不会在第一次值更改时出现明显延迟。

于 2018-01-20T21:31:37.473 回答