谁能帮助我找出是否我的文本框的文本没有改变一秒钟或不在MVVM模式(使用WPF)。
在我的ViewModel中,我有一个属性public String SearchText
{
get
{
return _searchString;
}
set
{
_searchString = value;
_functionProvidersView.Refresh();
}
}
,其中_functionProvidersView
属于ObservableCollection<FunctionProviderViewModel>
类型。我希望刷新只发生在文本一秒钟内没有改变的情况下。
我试图用System.Threading
解决这个问题,但没有做到这一点,有人有一个简单的解决方案吗?
编辑:基于SearchText
我的集合被过滤。因为我的Filter机制需要一些时间,所以我希望只有当用户在一秒钟内没有更改Textbox文本(没有键入任何内容)时才会进行过滤。
文本框属性UpdateSourceTrigger
设置为PropertyChanged
。我可以将其设置为LostFocus
,但这不是我想要的。
一种方法是使用计时器延迟刷新调用:
public class MainVm
{
System.Threading.Timer timer;
private string searchText = string.Empty;
public string SearchText
{
get { return searchText; }
set
{
searchText = value;
timer.Change(1000, System.Threading.Timeout.Infinite); //reset the timer
}
}
public MainVm()
{
timer = new System.Threading.Timer(RefreshView,
null,
System.Threading.Timeout.Infinite,
System.Threading.Timeout.Infinite);
}
private void RefreshView(object state)
{
//Here you need to use the dispatcher because the callback is called
//from a non-UI thread
Application.Current.Dispatcher.Invoke(new Action(() =>
_functionProvidersView.Refresh()
);
}
}
通过这种方式,RefreshView
方法将在您停止输入
你必须像RaisePropertyChanged
那样触发事件
public String SearchText
{
get
{
return _searchString;
}
set
{
_searchString = value;
RaisePropertyChanged("functionProvidersView");
}
}
WPF方法
- 在TextChanged事件上定义storyboard
添加了一个布尔动画,两帧在0时为假,在1秒时为真(你可以根据你的需要自定义,也许绑定到设置)
<TextBox> <TextBox.Triggers> <EventTrigger RoutedEvent="TextBox.TextChanged" > <BeginStoryboard> <Storyboard> <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="DataContext.TextChanged" > <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" /> <DiscreteBooleanKeyFrame KeyTime="0:0:1" Value="True"/> </BooleanAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </TextBox.Triggers> </TextBox>
这将在文本更改时触发属性更改,并在1秒后将值发送为true
视图模型代码
- 在视图模型中添加了一个属性来触发刷新
在OnChanged处理程序,我将执行我的逻辑刷新等
public bool TextChanged { get { return (bool)GetValue(TextChangedProperty); } set { SetValue(TextChangedProperty, value); } } // Using a DependencyProperty as the backing store for TextChanged. This enables animation, styling, binding, etc... public static readonly DependencyProperty TextChangedProperty = DependencyProperty.Register("TextChanged", typeof(bool), typeof(ViewModel), new PropertyMetadata(false,OnTextChanged)); private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if ((bool)e.NewValue) { //your logic after 1 second (d as ViewModel)._functionProvidersView.Refresh(); } }
在这种方法中,你不必手动管理定时器,它将由wpf
处理。