我想爲WPF創建一種基於Rx的ICommand。我想要做的是能夠通過組合任意數量的IObservable流來控制CanExecute。如何組合多個IObservable <bool>以形成複合bool訂閱值
我想工作的方式是我想使用所有謂詞的最新組合邏輯與值,並使用它來控制bool ICommand.CanExecute(object parameter)方法實現。我不想等所有的謂詞產生,它應該使用任何一個源謂詞流OnNexts(產生一個值)。
我試圖弄清楚如何連接它,以致任何謂詞都應該導致ICommand.CanExecute產生一個新的值。
忘記實際的ICommand實現一分鐘(因爲我的問題是更多的東西RX端),任何人都可以建議我怎麼能連線了一堆謂詞(的IObservable <布爾>),其產量每當底層的東西創造他們的流改變,但也將一致工作,以創建一個我可以訂閱的整體結束價值。結束值將是當前謂詞流值的邏輯與。
我希望我不需要訂閱所有的謂詞流,並且希望在RX內有一個很酷的運算符,我可能忽略了它。
我知道我可以合併流,但這並不完全是我之後的行爲,因爲這僅僅是來自已合併的輸入流的最新值,我也知道我可以CombineLatest,但這不是非常正確,因爲只有當所有的合併流產生價值時它纔會產生。
我想要的是要組合的流,所以任何更改都會通知訂閱者,但我也想知道什麼邏輯與操作組合的謂詞IObservable流現在是正確的,這樣我就可以驅動ICommand.CanExecute從這個整體組合值。
我希望這是有道理的。
下面是一些骨架代碼(我已經留下了一些註釋掉的代碼,這說明背後說我的Rx指揮理念的思考,因爲它可能有助於說明什麼,我想工作)
public class ViewModel : INPCBase
{
private string title;
private bool hasStuff;
public ViewModel()
{
//Initialise some command with 1st predicate, and
// initial CanExecute value
//SomeCommand = new ReactiveCommand(
// this.ObserveProperty(x => x.Title)
// .Select(x => !string.IsNullOrEmpty(x)), false);
//SomeCommand.AddPredicate(this.ObserveProperty(x => x.HasStuff));
//SomeCommand.CommandExecutedStream.Subscribe(x =>
// {
// MessageBox.Show("Command Running");
// });
IObservable<bool> obsPred = this.ObserveProperty(x => x.Title)
.Select(x => !string.IsNullOrEmpty(x))
.StartWith(!string.IsNullOrEmpty(this.Title));
IObservable<bool> obsPred2 = this.ObserveProperty(x =>
x.HasStuff).StartWith(this.HasStuff);
obsPred.Merge(obsPred2).Subscribe(x =>
{
//How do I get this to fire whenever obsPred OR
//obsPred2 fire OnNext, but also get a combined value (bool)
//of the AND of obsPred & obsPred2 (bearing in mind I may
//want more than 2 predicates, it should cope with any number of
//IObservable<bool> predicates
});
}
public string Title
{
get
{
return this.title;
}
set
{
RaiseAndSetIfChanged(ref this.title, value,() => Title);
}
}
public bool HasStuff
{
get
{
return this.hasStuff;
}
set
{
RaiseAndSetIfChanged(ref this.hasStuff, value,() => HasStuff);
}
}
}
李我也嘗試CombineLatest/DistinctUntilChanged組合,但並不意味着你必須等待所有的輸入流,以產生。說實話,我嘗試了一些我可能會感到困惑的事情。我會在早上給它穿過。我相信你是對的。你是上次。我看到你現在也從加拿大銀行轉移過來。喜歡新的地方?對我而言,我肯定會進入Rx,它的成癮性讓你在這裏有點想象,然後它突然在那兒變得很好。我認爲這是可以的。 – sacha
啊哈我想我知道爲什麼我使用CombineLatest的嘗試沒有按預期工作。在你的博客中「CombineLatest擴展方法允許你從兩個序列中獲取最近的值,並且給定的函數將它們轉換爲結果序列的值,每個輸入序列都有最後一個緩存的值,如Replay(1)。兩個序列都產生了至少一個值,每次序列產生一個值時,每個序列的最新輸出都傳遞給resultSelector函數......「所以我認爲我需要使用StartsWith(false)作爲初始值 – sacha
Still I將明天嘗試它,讓你知道,並且一旦我知道你的答案是正確的,就投票給你(確定它會是;-)) – sacha