我要求在用户开始输入时关闭某个功能,这很简单。当用户停止输入时,我想重新打开该功能。
如果没有响应式扩展,可以简单地使用 timer
来实现此功能,它会在每次 last keystroke 时将计时器重置为 1 秒
并且当用户停止输入并且计时器计时结束
功能重新打开。
有什么方法可以调用来实现与 Reactive Extensions
相同的效果吗?
Throttle
或 Timeout
每 1 秒
更新
XAML
<RichTextBox MaxHeight="1000" VerticalScrollBarVisibility="Visible" x:Name="meh"/>
扩展类
public static IObservable<EventArgs> ObserveTextChanged(this RichTextBox rtb)
{
return Observable.FromEventPattern<TextChangedEventHandler, EventArgs>(
h => rtb.TextChanged += h,
h => rtb.TextChanged -= h)
.Select(ep => ep.EventArgs);
}
Class 其中 meh
是 RichTextBox
public class MainWindow()
{
//Change this to be the keypress/propertychagned event. The type T doesn't matter we ignore it
var typing = meh.ObserveTextChanged().Take(4);
var silence = meh.ObserveTextChanged().IgnoreElements();
var source = typing.Concat(silence).Concat(typing);
var disableSpellcheck = source.Select(_ => false);
var enableSpellcheck = source.Select(_ => Observable.Timer(TimeSpan.FromSeconds(1)))
.Switch()
.Select(_ => true);
disableSpellcheck.Merge(enableSpellcheck)
.DistinctUntilChanged()
.Subscribe(SetFlag);
}
// Define other methods and classes here
public void SetFlag(bool flag)
{
Dispatcher.Invoke(new Action(() => SpellCheck.SetIsEnabled(meh, flag)));
Debug.Write("flag");
}
最佳答案
这里是展示如何将上面的代码移植到 WPF 的所有代码。看来这里的沟通存在差距,所以我创建了整个 wpf 应用程序来证明这一点。
<Window x:Class="StackoverFlow_23764884.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<HeaderedContentControl Header="When checked, spellcheck is enabled (emulated)">
<CheckBox x:Name="spellChecking" IsChecked="True" IsEnabled="False"/>
</HeaderedContentControl>
<HeaderedContentControl Header="Type here to see the Spellcheck enable and disable">
<RichTextBox x:Name="meh" Width="400" Height="300" />
</HeaderedContentControl>
</StackPanel>
</Window>
以及背后的代码:
using System;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Controls;
namespace StackoverFlow_23764884
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var source = meh.ObserveTextChanged();
var disableSpellcheck = source.Select(_ => false);
var enableSpellcheck = source.Select(_ => Observable.Timer(TimeSpan.FromSeconds(1)))
.Switch()
.Select(_ => true);
disableSpellcheck.Merge(enableSpellcheck)
.DistinctUntilChanged()
.ObserveOnDispatcher()
.Subscribe(isEnabled => spellChecking.IsChecked=isEnabled);
}
}
public static class ObEx
{
public static IObservable<EventArgs> ObserveTextChanged(this RichTextBox rtb)
{
return Observable.FromEventPattern<TextChangedEventHandler, EventArgs>(
h => rtb.TextChanged += h,
h => rtb.TextChanged -= h)
.Select(ep => ep.EventArgs);
}
}
}
我拉入 Rx-WPF nuget packeage 将拉取代码所需的所有其他内容。这是 .NET 4.5。
这是一个演示如何解决问题的示例。也就是说,我不建议使用 .ObserveOnDispatcher()
,我不建议编写代码隐藏,而且我知道在复选框上设置 IsEnabled 实际上不是在进行拼写检查。我希望这足以让观众重新创建他们的实际解决方案。
不过还是希望对你有所帮助。
关于c# - 有没有办法听到 Reactive Extensions 中没有引发任何事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23764884/