【问题标题】:Delay timer for KeyDown eventKeyDown 事件的延迟计时器
【发布时间】:2014-09-27 13:47:45
【问题描述】:

我有一个Textbox,它有一个KeyDown 事件。此事件与 ViewModel 中的事件处理程序绑定。下面是示例代码:

<TextBox x:Name="textBox" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding Path=TextBoxKeyDownEvent}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
<TextBox.InputBindings>

确实,一旦用户开始在 texbox 中写入,ViewModel 中的后端事件处理程序就会被调用。但我不想为每个 KeyDown 操作调用事件处理程序。当用户开始在文本框中输入并停止至少 N 毫秒时,我想调用事件处理程序。这意味着我需要为事件设置一个延迟计时器。谁能指导我如何在 MVVM 中实现这一目标?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    您可以使用BindingBase.Delay 属性:

    <TextBox x:Name="textBox" Text="{Binding TextBoxText, Delay=500, UpdateSourceTrigger=PropertyChanged}" />
    

    这将在用户更改视图模型中的 TextBoxText 属性仅 500 毫秒后修改它。然后,在您的 setter 中,您可以调用任何您想执行的代码。

    private string textBoxText;
    public string TextBoxText
    {
        get { return textBoxText; }
        set
        {
            // Setter will be called only 500 milliseconds after the user has entered text.
            if (textBoxText != value)
            {
                textBoxText = value;
                RaisePropertyChanged("TextBoxText");
    
                // Handle text change.
                DoStuff();
            }
        }
    }
    

    编辑:

    如果您希望在代码中更改属性时也发生延迟,您可以使用类似于此处提到的解决方案的方法:Timer to fire an event WPF

    【讨论】:

    • 感谢您的建议。但我不能在 TextProperty Change 事件中使用它。因为文本可以由程序内部更改。所以这里的事件处理程序只有在文本更改发生时才会起作用。这就是为什么我需要使用 keydown 事件。
    • 我想我没能让你明白我的目的。我有一个文本框,在每个按键的文本框中都有一个命令绑定。该 Binded 方法调用视图和视图从数据库中获取数据。但我不希望每次按键都会调用绑定方法。我希望如果用户停止输入一段时间(比如 500 毫秒),那么只有绑定的方法才会被调用。
    • 注意:此属性是 .NET 4.5 的新属性
    【解决方案2】:

    设置定时器和超时事件

        private System.Timers.Timer keypressTimer = new System.Timers.Timer();
        keypressTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
    

    在超时事件中做你的任务 -

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            keypressTimer.Stop();
            App.Current.Dispatcher.Invoke((Action)delegate
            {
    
                //CALL YOUR EVENT HERE
    
            });
    
        }
    

    每次按键都会被按下 - 您需要通过以下方式重置计时器。

        if (delayTime > 0)
                {
                    keypressTimer.Interval = delayTime;
                    keypressTimer.Start();
                }
    

    【讨论】:

      猜你喜欢
      • 2012-07-11
      • 2015-07-08
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多