我试图理解下面的代码试图使用反应式扩展
IObservable<string> textChangedObservable =
Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
.Select(evt => ((TextBox) sender).Text);
textChangedObservable.Subscribe(OnNext, OnCompleted);
private void OnNext(string s)
{
System.Diagnostics.Debug.Print("OnNext " + s + "\n");
}
private void OnCompleted()
{
System.Diagnostics.Debug.Print("OnCompleted " + "\n");
}
如果我在输入框中输入SEARC,则输出看起来
OnNext SEARC
答案 0 :(得分:3)
您似乎订阅了searchScrip_TextChanged
处理程序中的observable。
这意味着第一次searchScrip_TextChanged
被调用S
已经发生之前您已连接了observable。所以当然不会开火。
但是现在S
已被点击,您有一个订阅,因此当输入E
时,您会获得一个SE
。但是由于searchScrip_TextChanged
处理程序也被调用E
,你现在有两个订阅你的observable。
因此,当输入A
时,您会得到两个SEA
,因为您有两个可观察对象。但是再次为searchScrip_TextChanged
调用了A
,所以现在你有三个可观察量。
Etc等等。
事件未自动完成。您需要手动处理订阅以使它们结束。这应该是有意义的,因为这是你想要停止的普通事件处理程序所必须做的。
您应该在加载表单时创建observable,以便创建一次。
它应该是这样的:
IObservable<string> textChangedObservable =
Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
.Select(evt => searchScrip.Text);
IDisposable subscription =
textChangedObservable
.Subscribe(
s => Debug.Print("OnNext " + s + "\n"),
s => Debug.Print("OnCompleted\n"));
答案 1 :(得分:2)
这里的问题与Rx无关。
1:为什么&#34; S&#34;没有触发OnNext?
因为您订阅的TextChanged
事件未在第一个S上触发。
2:为什么OnCompleted从未被调用过?
当您将.NET事件包装为IObservable<T>
时,您永远不会收到OnError
或OnCompleted
次通知。 .NET事件没有错误或完成的概念。
如果有两个事件,一个用于值,一个用于完成,您可以将它们组合起来:
var values = Observable.FromEvent(...);
var completion = Observable.FromEvent(...);
var query = values.TakeUntil(completion);
现在query
会产生正确的OnCompleted
通知。
3:为什么OnNext在第n个字符上调用了n-1次?
因为您已订阅的TextChanged
事件以此方式触发。正如@ Kari-Antti所指出的,这可能是使用&#34;路由属性的副作用&#34;事件
答案 2 :(得分:-1)
也许是因为你使用过RoutedPropertyChangedEventArgs?
如果使用PropertyChangedEventHandler怎么办?
%let text = abc\pqr{work};
data _null_;
var=prxchange("s/\\/\\\\/",-1,"&text");
var=prxchange("s/\{/\\\{/",-1,var);
var=prxchange("s/\}/\\\}/",-1,var);
put var;
run;