以前の質問で、F# アプリケーションのオブザーバー パターンを慣用的に実装する方法を尋ねました。私のアプリケーションは推奨されるようにMailboxProcessorを使用するようになり、サブ MailboxProcessor などを作成するヘルパー関数をいくつか作成しました。しかし、GUI バインディングに関する特定のケース シナリオになると、私は精神的ブロックに陥っています。
私はそのようなモデルを持っているとしましょう:
type Document = {
Contents : seq<DocumentObject>
}
また、GUI (WPF、XAML) には次のようなバインドが必要です。
interface IMainWindowViewModel
{
IEnumerable<Control> ContentViews { get; }
}
each ViewModelfor eachには、 (その基礎となるモデル)と、それが変更されたかどうかを知る方法Controlが必要です。変更が正しく反映されるようにDocumentObject、これをサブとして提供します。このパターンが機能することはある程度確信しています。MailboxProcessor<DocumentObject>基本的に、サービス出力をマッピングし、変更要求をラップします (以下の外部インターフェイスの例)。
let subSvc = generateSubSvc svc (fun doc -> doc.Contents[0]) (fun f -> fun oldDoc -> { oldDoc with Contents[0] = f Contents[0] })
let viewModel = new SomeDocObjViewModel(docObjSvc)
new DocObjView(viewModel)
DocumentObjectここで、変更コマンドがfrom を削除すると想像してくださいMyDocument。トップレベルは、それを使用するようMailboxProcessorに変更をエコーします。そして、ここから私の問題が始まります。IMainWindowViewModelIEvent<MyDocument>
どれが削除されたのか、私にはよくわかりIMainWindowViewModelません。新しいものがあり、それに対処しなければならないということだけです。理解する方法はあるかもしれませんが、実際に直接知ることは決してありません。これにより、すべての を安全 (非効率) にするために、すべての を再作成しなければならないという道を余儀なくされる可能性があります。簡潔にするためにここでは触れていない追加の問題 ( dangling など) もあります。DocumentObjectDocumentControlDocumentObjectsubSvc
通常、この種の動的な変更ObservableCollection<DocumentObject>は、 にマップされる のようなもので処理されますObservableCollection<Control>。これには、変更可能な共有状態のすべての警告が伴い、少し「ハック」です。ただし、それは仕事をします。
PropertyChanged理想的には、との罠から解放された「純粋な」モデルObservableCollectionsが欲しいのですが、F# のどのようなパターンがこのニーズを満たすでしょうか? 慣用的なものと現実的なもののどこに線を引くのが適切ですか?