我試圖從Silverlight應用程序中刪除更多的傳統事件處理程序,以支持使用多個Rx查詢來提供更好,更易於管理,行爲抽象。結合反應框架(Rx)查詢提供正確的UI行爲的問題
我需要解決的問題,但不能以我想要的方式完全破解它,正在使搜索屏幕的行爲發揮作用。這是非常標準的東西。這是它應該如何表現:
- 我有一個文本框中,用戶可以進入搜索文本。
- 如果沒有文本(或空格只)那麼搜索按鈕是禁用。
- 當有非空白文本那麼搜索按鈕是啓用。
- 當用戶點擊搜索的文本框中和搜索按鈕都禁用。
- 當結果回來的文本框中和搜索按鈕都啓用。
我有這些觀測值(通過一些擴展方法在標準事件創建)一起工作:
IObservable<IEvent<TextChangedEventArgs>> textBox.TextChangedObservable()
IObservable<IEvent<RoutedEventArgs>> button.ClickObservable()
IObservable<IEvent<LoadingDataEventArgs>> dataSource.LoadingDataObservable()
IObservable<IEvent<LoadedDataEventArgs>> dataSource.LoadedDataObservable()
我的這些疑問,在目前的工作:
IObservable<bool> dataSourceIsBusy =
dataSource.LoadingDataObservable().Select(x => true)
.Merge(dataSource.LoadedDataObservable().Select(x => false));
IObservable<string> textBoxText =
from x in textBox.TextChangedObservable()
select textBox.Text.Trim();
IObservable<bool> textBoxTextIsValid =
from text in textBoxText
let isValid = !String.IsNullOrEmpty(text)
select isValid;
IObservable<string> searchTextReady =
from x in button.ClickObservable()
select textBox.Text.Trim();
而且那麼這些訂閱將它連接起來:
buttonIsEnabled.Subscribe(x => button.IsEnabled = x);
dataSourceIsBusy.Subscribe(x => textBox.IsEnabled = !x);
searchTextReady.Subscribe(x => this.ExecuteSearch(x));
(我確實保留對Subscribe
方法返回的一次性用品的參考。我已將.ObserveOnDispatcher()
添加到每個observable,以確保代碼在UI線程上運行。)
現在,雖然這有效,但有一件事情會讓我感到困擾。 searchTextReady
中的select語句調用textBox.Text.Trim()
來獲取當前修剪的搜索文本,但我已經在textBoxText
可觀察值中完成了此操作。我真的不想重複自己,所以我想創建一個查詢,結合這些observables,這是我失敗的地方。
當我嘗試下面的查詢我得到重入調用來執行搜索:
IObservable<string> searchTextReady =
from text in textBoxText
from x in button.ClickObservable()
select text;
下面的查詢,似乎爲第一查詢工作,但後來我每次更改文本中
IObservable<string> searchTextReady =
from text in button.ClickObservable()
.CombineLatest(textBoxText, (c, t) => t)
select text;
下面的查詢需要進一步的文本改變點擊搜索按鈕後,會出現,然後未能再次運行:
文本框後的搜索無需點擊搜索按鈕被自動執行IObservable<string> searchTextReady =
from text in textBoxText
.SkipUntil(button.ClickObservable())
.TakeUntil(dataSource.LoadingDataObservable())
select text;
任何想法,我可以使這項工作?
對不起,但'ForkJoin'只結合了observables的最後一個值(它們也需要是相同的類型)。每次點擊搜索按鈕時,我都想讓'searchTextReady'觀察值觸發並返回最新的,而不是最後的'textBoxText'值。不管怎麼說,還是要謝謝你。 – Enigmativity 2010-10-19 02:25:41