рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛: рдмрджрд▓рддреЗ рд╕рдВрдЧреНрд░рд╣, рдПрдорд╡реАрд╡реАрдПрдо рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди, рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди

рдлрд░рд╡рд░реА 2019 рдореЗрдВ, ReactiveUI 9 , Microsoft .NET рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдкрд░ GUI рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред ReactiveUI MVVM рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЛ рдХрд╕рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рд╣реИред рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдиреЗ рдХреА рд╢реБрд░реБрдЖрдд рд╣реИрдмреЗ рдкрд░ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рд╛рде рдпрд╛ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдкрд╣рд▓реЗ рдкреГрд╖реНрда рд╕реЗ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ ред ReactiveUI 9 рдЕрдкрдбреЗрдЯ рдореЗрдВ рдХрдИ рдлрд╝рд┐рдХреНрд╕реЗрд╕ рдФрд░ рд╕реБрдзрд╛рд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ , рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрджрд▓рд╛рд╡ рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рддрдВрдЧ рдПрдХреАрдХрд░рдг рд╣реИ , рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╢реИрд▓реА рдореЗрдВ рдмрджрд▓рддреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдЗрдП рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдХрд┐ рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдХрд┐рди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдЖ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреИрд╕реЗ рдЗрд╕ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдврд╛рдВрдЪреЗ рдХреЛ рдЕрдВрджрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ!

рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрддреЗрдВ


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╢реНрд░реЗрдгреА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдбрд╛рдпрдирд╛рдореЗрдЯрд╛рдЯрд╛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ рдХрд┐ System.Collections.ObjectModel рд╕реЗ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдмрджрд▓рдиреЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рдЙрдкрдХрд░рдг рдХреНрдпреЛрдВ рд╣реИрдВред

рдПрдорд╡реАрд╡реАрдПрдо рдЯреЗрдореНрдкрд▓реЗрдЯ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЖрд╡реЗрджрди рдХреА рдореЙрдбрд▓, рдкреНрд░рд╕реНрддреБрддрд┐ рдФрд░ рдкреНрд░рд╕реНрддреБрддрд┐ рдореЙрдбрд▓ рдХреА рдкрд░рддреЛрдВ рдХреЗ рдмреАрдЪ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХрд╛ рд╡рд┐рднрд╛рдЬрди рд╢рд╛рдорд┐рд▓ рд╣реИред рдореЙрдбрд▓ рдкрд░рдд рдХреЛ рдбреЛрдореЗрди рд╕рдВрд╕реНрдерд╛рдУрдВ рдФрд░ рд╕реЗрд╡рд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рд╕реНрддреБрддрд┐ рдореЙрдбрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдкрддрд╛ рд╣реИред рдореЙрдбрд▓ рдкрд░рдд рдкреВрд░реЗ рдЬрдЯрд┐рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддрд░реНрдХ рдХреЛ рд╕рдорд╛рд╣рд┐рдд рдХрд░рддреА рд╣реИ, рдФрд░ рдкреНрд░рд╕реНрддреБрддрд┐ рдореЙрдбрд▓ рдореЙрдбрд▓ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдЧреБрдгреЛрдВ, рдЖрджреЗрд╢реЛрдВ рдФрд░ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрд╡реЗрджрди рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдмрджрд▓рддреЗ рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рдЙрдкрдХрд░рдг INotifyCollectionChanged рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ INotifyCollectionChanged , рдФрд░ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдФрд░ ObservableCollection рдФрд░ INotifyCollectionChanged рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ INotifyCollectionChanged ред



INotifyPropertyChanged рдФрд░ ICommand рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдорддреМрд░ рдкрд░ рдбреЗрд╡рд▓рдкрд░ рдФрд░ MVVM рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд░рд╣рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди ObservableCollection рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдкрд░ рдХрдИ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддрд╛ рд╣реИ! рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо Dispatcher.Invoke рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреА рдХреЙрд▓ рдХреЗ рдмрд┐рдирд╛ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдереНрд░реЗрдб рд╕реЗ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдбреЗрдЯрд╛ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдкреГрд╖реНрдарднреВрдорд┐ рдСрдкрд░реЗрд╢рди рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рд╣реЛрддреЗ рд╣реИрдВред рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдореБрд╣рд╛рд╡рд░реЗрджрд╛рд░ MVVM рдореЗрдВ, рдореЙрдбрд▓ рд▓реЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП GUI рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ MVC рдпрд╛ MVP рд╕реЗ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдХрдИ Dispatcher.Invoke рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдереНрд░реЗрдб рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд┐рдпрдВрддреНрд░рдг рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рдПрдХ рдбреЛрдореЗрди рд╕реЗрд╡рд╛ рдореЗрдВ, рдЖрд╡реЗрджрди рдкрд░рддреЛрдВ рдХреЗ рдмреАрдЪ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддреЗ рд╣реИрдВред

рдмреЗрд╢рдХ, рдПрдХ рдбреЛрдореЗрди рд╕реЗрд╡рд╛ рдореЗрдВ рдПрдХ рдШрдЯрдирд╛ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдФрд░ рдПрдХ рдШрдЯрдирд╛ рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдмрджрд▓реЗ рд╣реБрдП рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдЪрдВрдХ рдкрд╛рд╕ рдХрд░реЗрдВред рддрдм рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдВ, рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ Dispatcher.Invoke рдХреЙрд▓ рдХреЛ рд▓рдкреЗрдЯреЗрдВ рддрд╛рдХрд┐ рдпрд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдП рдЧрдП рдЬреАрдпреВрдЖрдИ рдврд╛рдВрдЪреЗ рдкрд░ рдирд┐рд░реНрднрд░ рди рд╣реЛ, Dispatcher.Invoke рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВред рдкреНрд░рд╕реНрддреБрддрд┐ рдореЙрдбрд▓ рдореЗрдВ рдмрджрд▓реЗрдВ рдФрд░ рдЬрд░реВрд░рдд рдХреЗ рдЕрдиреБрд╕рд╛рд░ ObservableCollection рдмрджрд▓реЗрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдмрд╛рдЗрдХ рдХреЛ рд▓рд┐рдЦреЗ рдмрд┐рдирд╛ рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рддрд░реАрдХрд╛ рд╣реИред ред рдЪрд▓реЛ рдЕрдзреНрдпрдпрди рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ!

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╡рд┐рд╕реНрддрд╛рд░ред рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░реЗрдВ


рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рджреНрд╡рд╛рд░рд╛ рдкреЗрд╢ рдХрд┐рдП рдЧрдП рдЕрдореВрд░реНрддрддрд╛рдУрдВ рдФрд░ рдмрджрд▓рддреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреА рдкреВрд░реА рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ Microsoft .NET рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдФрд░ MVVM рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП ред рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрдВрдЯрд░рдПрдХреНрдЯрд┐рд╡ рдмрд╛рддрдЪреАрдд рдореЗрдВ, рдЙрдкрднреЛрдХреНрддрд╛ рдлрд╝рдВрдХреНрд╢рди рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдлрд╝рдВрдХреНрд╢рди (рдкреБрд▓-рдЖрдзрд╛рд░рд┐рдд рдЕрдкреНрд░реЛрдЪ, T , IEnumerable ) рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдореЗрдВ, рдЙрдкрднреЛрдХреНрддрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕рд▓реА рдЙрдкрднреЛрдХреНрддрд╛ рдлрд╝рдВрдХреНрд╢рди (рдкреБрд╢-рдЖрдзрд╛рд░рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг, Task , IObservable ) рдХреЛ рдбреЗрдЯрд╛ рдбрд┐рд▓реАрд╡рд░ рдХрд░рддрд╛ рд╣реИред



рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдбреЗрдЯрд╛ рдзрд╛рд░рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рд╣реИ, рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдиреЗрдорд╕реНрдкреЗрд╕ рд╕реЗ IObservable рдФрд░ IObserver рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬреЛ IObservable рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рдХрдИ IObservable рдЬреИрд╕реЗ рдСрдкрд░реЗрд╢рдиреНрд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЗрдВ LINQ рдУрд╡рд░ IObservable рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди .NET рдорд╛рдирдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЬрд╣рд╛рдВ рднреА Microsoft .NET рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╡рд╣рд╛рдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред



ReactiveUI рдлреНрд░реЗрдорд╡рд░реНрдХ, рдПрдкреНрд▓реАрдХреЗрд╢рди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ ReactiveCommand<TIn, TOut> рдФрд░ WhenAnyValue рдХреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ ReactiveCommand<TIn, TOut> рдФрд░ WhenAnyValue рдЬреИрд╕реЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред WhenAnyValue рдПрдХ рд╡рд░реНрдЧ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ IObservable<T> рдкреНрд░рдХрд╛рд░ рдХреА рдШрдЯрдирд╛ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ IObservable<T> , рдЬреЛ рдЖрд╢реНрд░рд┐рдд рдЧреБрдгреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред

 public class ExampleViewModel : ReactiveObject { [Reactive] //  ReactiveUI.Fody,  // -  // OnPropertyChanged   Name. public string Name { get; set; } public ExampleViewModel() { //  OnPropertyChanged("Name"). this.WhenAnyValue(x => x.Name) //   IObservable<string> .Subscribe(Console.WriteLine); } } 

ReactiveCommand<TIn, TOut> рдЖрдкрдХреЛ рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдкреНрд░рдХрд╛рд░ IObservable<TOut> рдХреА рдПрдХ рдШрдЯрдирд╛ рдХреЗ рд╕рд╛рде, рдЬреЛ рдЬрдм рднреА рдХрдорд╛рдВрдб рдкреВрд░рд╛ рд╣реЛрддрд╛ рд╣реИ, рддрдм рдЗрд╕реЗ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд┐рд╕реА рднреА рдХрдорд╛рдВрдб рдореЗрдВ IObservable<Exception> рдкреНрд░рдХрд╛рд░ рдХреА ThrownExceptions рд╕рдВрдкрддреНрддрд┐ рд╣реИред

 // ReactiveCommand<Unit, int> var command = ReactiveCommand.Create(() => 42); command //   IObservable<int> .Subscribe(Console.WriteLine); command .ThrownExceptions //   IObservable<Exception> .Select(exception => exception.Message) //   IObservable<string> .Subscribe(Console.WriteLine); command.Execute().Subscribe(); // : 42 

рдпрд╣ рд╕рдм рд╕рдордп рд╣рдордиреЗ IObservable<T> рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛, рдПрдХ рдШрдЯрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛ рдЯрд╛рдЗрдк T рдХрд╛ рдПрдХ рдирдпрд╛ рдорд╛рди рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрдм рднреА рд╡рд╕реНрддреБ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╣реЛрддрд╛ рд╣реИред рд╕реАрдзреЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдХрд╣реЗрдВ, IObservable<T> рдШрдЯрдирд╛рдУрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рд╣реИ, рдПрдХ рдЕрдиреБрдХреНрд░рдо рд╕рдордп рдХреЗ рд╕рд╛рде рдмрдврд╝рд╛ред

рдмреЗрд╢рдХ, рд╣рдо рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЬрдм рднреА рдХреЛрдИ рд╕рдВрдЧреНрд░рд╣ рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ рдмрджрд▓реЗ рд╣реБрдП рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░реЗрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдкреНрд░рдХрд╛рд╢рд┐рдд рдорд╛рди IEnumerable<T> рдпрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛрдЧрд╛, рдФрд░ рдШрдЯрдирд╛ рд╕реНрд╡рдпрдВ IObservable<IEnumerable<T>> рдкреНрд░рдХрд╛рд░ рдХреА IObservable<IEnumerable<T>> ред рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдЧрдВрднреАрд░ рд░реВрдк рд╕реЗ рд╕реЛрдЪрдиреЗ рд╡рд╛рд▓реЗ рдкрд╛рдардХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрддрд╛рддреЗ рд╣реИрдВ, рдпрд╣ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдЧрдВрднреАрд░ рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рднрд░рд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдПрдХ рджрд░реНрдЬрди рддрддреНрд╡ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╕реМ, рдпрд╛ рдХрдИ рд╣рдЬрд╛рд░ рднреА рд╣реИрдВ!

рдбрд╛рдпрдирд╛рдореИрдЯрдбрд╛рдЯрд╛ рдХрд╛ рдкрд░рд┐рдЪрдп


рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдкреВрд░реА рд╢рдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрджрд▓рддреЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╖реНрдЯрддрдо рддрд░реАрдХреЗ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдХрд╛ рдХрд╛рдо рдЗрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ, рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ - рдЖрдорддреМрд░ рдкрд░, рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдХреБрдЫ рддрддреНрд╡реЛрдВ рд╕реЗ рднрд░рд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрд╡реЗрджрди рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рд╕рд░реНрд╡рд░ рдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рддрд╛ рд╣реИред рдЖрдзреБрдирд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╣реИрдВ, рдФрд░ рдЕрдХреНрд╕рд░ рд╕рдВрдЧреНрд░рд╣ рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ - рдлрд╝рд┐рд▓реНрдЯрд░, рдкрд░рд┐рд╡рд░реНрддрди рдпрд╛ рд╕реЙрд░реНрдЯ рддрддреНрд╡ред рдбрд╛рдпрдирд╛рдореИрдЯрдбрд╛рдЯрд╛ рдХреЛ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдЬрдЯрд┐рд▓ рдХреЛрдб рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдмрджрд▓рддреЗ рдбреЗрдЯрд╛ рд╕реЗрдЯреЛрдВ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЙрдкрдХрд░рдг рдХреЛ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдФрд░ рдЕрдВрддрд┐рдо рд░реВрдк рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЕрдм рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 60 рд╕реЗ рдЕрдзрд┐рдХ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рд╣реИред



рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ ObservableCollection<T> рдХрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВ рд╣реИред рдбрд╛рдпрдирд╛рдореИрдЯрдбрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдбреЛрдореЗрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдЙрдкрдпреЛрдЧ рдХреА рд╡рд┐рдЪрд╛рд░рдзрд╛рд░рд╛ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдХрд┐ рдЖрдк рдХреБрдЫ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдЬреЛ рдбреЗрдЯрд╛ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдФрд░ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдХрдИ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рд╕реНрд░реЛрдд рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрдк рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдмрдирд╛рдиреЗ рдФрд░ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛, рдбреЗрдЯрд╛ рдХреЛ рдШреЛрд╖рд┐рдд рд░реВрдк рд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдХреЗ рд╕рд╛рде рдЖрдк рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЖрдк рдХреЗрд╡рд▓ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рддрд░реАрдХреЗ рд╕реЗ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ - рдЗрд╕рд▓рд┐рдП, рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗ рд╕рдВрдЧреНрд░рд╣ рд╣рдореЗрд╢рд╛ рд╕реНрд░реЛрдд рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред

рдХреНрд▓рд╛рд╕рд┐рдХ IObservable<T> рдмрдЬрд╛рдп, IObservable<IChangeSet<T>>> рдФрд░ IObservable<IChangeSet<TValue, TKey>> IObservable<IChangeSet<T>>> рдкрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ IChangeSet рд╕рдВрдЧреНрд░рд╣ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╡рд╛рд▓рд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ - рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рддрддреНрд╡ред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдХрд╛рдлреА рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, IObservable<IChangeSet<T>> рдХреЛ рд╣рдореЗрд╢рд╛ рдПрдХ рдирд┐рдпрдорд┐рдд IObservable<IEnumerable<T>> рдореЗрдВ рддрдмреНрджреАрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдЧрд░ рдПрдХ рдмрд╛рд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдЬрдЯрд┐рд▓ рд▓рдЧрддрд╛ рд╣реИ - рдЪрд┐рдВрддрд╛ рдордд рдХрд░реЛ, рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдФрд░ рдкрд╛рд░рджрд░реНрд╢реА рд╣реЛ рдЬрд╛рдПрдЧрд╛!

рдбрд╛рдпрдирд╛рдорд╛рдбрд╛рдЯрд╛ рдЙрджрд╛рд╣рд░рдг


рдЖрдЗрдП рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рджреЗрдЦреЗрдВ рдХрд┐ рдбрд╛рдпрдирд╛рдорд╛рдбрд╛рдЯрд╛ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдпрд╣ System.Reactive рд╕реЗ рдХреИрд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ System.Reactive рдФрд░ GUI рдХреЗ рд╕рд╛рде рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд▓рд┐рдП GitHub рдкрд░ DynamicData рджреНрд╡рд╛рд░рд╛ рдкреЛрд╕реНрдЯ рдХрд┐рдП рдЧрдП рдПрдХ рд╡реНрдпрд╛рдкрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд SourceCache<Trade, long> , рдЬрд┐рд╕рдореЗрдВ рд▓реЗрдирджреЗрди рдХрд╛ рд╕рдВрдЧреНрд░рд╣ рд╣реЛрддрд╛ рд╣реИред рдХрд╛рд░реНрдп рдХреЗрд╡рд▓ рд╕рдХреНрд░рд┐рдп рд▓реЗрдирджреЗрди рджрд┐рдЦрд╛рдирд╛ рд╣реИ, рдореЙрдбрд▓ рдХреЛ рдкреНрд░реЙрдХреНрд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдмрджрд▓рдирд╛, рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд╕реЙрд░реНрдЯ рдХрд░рдирд╛ рд╣реИред

 //    System.Collections.ObjectModel, //       . ReadOnlyObservableCollection<TradeProxy> list; //   ,   . //   Add, Remove, Insert   . var source = new SourceCache<Trade, long>(trade => trade.Id); var cancellation = source //      . //   IObservable<IChangeSet<Trade, long>> .Connect() //       . .Filter(trade => trade.Status == TradeStatus.Live) //    -. //   IObservable<IChangeSet<TrandeProxy, long>> .Transform(trade => new TradeProxy(trade)) //    . .Sort(SortExpressionComparer<TradeProxy> .Descending(trade => trade.Timestamp)) //  GUI    . .ObserveOnDispatcher() //    - //    System.Collections.ObjectModel. .Bind(out list) // ,       //    . .DisposeMany() .Subscribe(); 

рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЬрдм рдЖрдк SourceCache рдХреЛ SourceCache , рдЬреЛ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╣реИ, рддреЛ ReadOnlyObservableCollection рднреА рдЙрд╕реА рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдмрджрд▓ ReadOnlyObservableCollection ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рдВрдЧреНрд░рд╣ рд╕реЗ рддрддреНрд╡реЛрдВ рдХреЛ рд╣рдЯрд╛рддреЗ рд╕рдордп, Dispose рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд╣рдореЗрд╢рд╛ рдХреЗрд╡рд▓ GUI рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЫрд╛рдВрдЯрд╛ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХреВрд▓, рдиреЛ Dispatcher.Invoke рдФрд░ рдХреНрд▓рд┐рд╖реНрдЯ рдХреЛрдб!

SourceList рдФрд░ SourceCache рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд


рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рджреЛ рд╡рд┐рд╢реЗрд╖ рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпреЗ рд╕рдВрдЧреНрд░рд╣ SourceList рдФрд░ SourceCache<TObject, TKey> ред рдЬрдм рднреА SourceCache рдкрд╛рд╕ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдХреБрдВрдЬреА рд╣реЛ, рддреЛ SourceCache рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдЕрдиреНрдпрдерд╛ SourceList рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдпреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдЪрд┐рдд .NET рдбреЗрд╡рд▓рдкрд░реНрд╕ рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ - Add , Remove , Insert рдФрд░ рдЬреИрд╕реЗред рдбреЗрдЯрд╛ рд╕реНрд░реЛрддреЛрдВ рдХреЛ IObservable<IChangeSet<T>> рдпрд╛ IObservable<IChangeSet<T, TKey>> рдореЗрдВ .Connect() рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП .Connect() рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдРрд╕реА рд╕реЗрд╡рд╛ рд╣реИ рдЬреЛ рдкреГрд╖реНрдарднреВрдорд┐ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреА рд╣реИ, рддреЛ рдЖрдк Dispatcher.Invoke рдмрд┐рдирд╛ рдЗрди рддрддреНрд╡реЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ GUI рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 public class BackgroundService : IBackgroundService { //    . private readonly SourceList<Trade> _trades; //     . //  ,     , //    Publish()  Rx. public IObservable<IChangeSet<Trade>> Connect() => _trades.Connect(); public BackgroundService() { _trades = new SourceList<Trade>(); _trades.Add(new Trade()); //    ! //    . } } 

рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдореИрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд .NET рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╢рдХреНрддрд┐рд╢рд╛рд▓реА IObservable<IChangeSet<Trade>> рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдЕрдкрдиреЗ рджреГрд╢реНрдп рдореЙрдбрд▓ рдХреЗ IObservable<IChangeSet<Trade>> ReadOnlyObservableCollection рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

 public class TradesViewModel : ReactiveObject { private readonly ReadOnlyObservableCollection<TradeVm> _trades; public ReadOnlyObservableCollection<TradeVm> Trades => _trades; public TradesViewModel(IBackgroundService background) { //   ,  ,  //     System.Collections.ObjectModel. background.Connect() .Transform(x => new TradeVm(x)) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out _trades) .DisposeMany() .Subscribe(); } } 

Transform , Filter рдФрд░ Sort , рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд╛рдЯрд╛ рдореЗрдВ рдЕрдиреНрдп рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╢рд╛рдорд┐рд▓ рд╣реИ, рд╕рдореВрд╣рди, рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЪреМрд░рд╕рд╛рдИ рдХрд░рддрд╛ рд╣реИ, рдПрдХрддреНрд░реАрдХрд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╕рдорд╛рди рддрддреНрд╡реЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рддрддреНрд╡реЛрдВ рдХреА рдЧрд┐рдирддреА, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рдореЙрдбрд▓ рдХреЗ рд╡рд░реНрдЪреБрдЕрд▓рд╛рдЗрдЬреЗрд╢рди рднреА рд╢рд╛рдорд┐рд▓ рд╣реИред GitHub рдкрд░ README рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕рднреА рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрдврд╝реЗрдВред



рдПрдХрд▓ рдереНрд░реЗрдбреЗрдб рд╕рдВрдЧреНрд░рд╣ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рдЯреНрд░реИрдХрд┐рдВрдЧ


SourceList рдФрд░ SourceCache рдЕрд▓рд╛рд╡рд╛, SourceCache рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдПрдХ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ - ObservableCollectionExtended ред рдЕрдкрдиреЗ рджреГрд╢реНрдп рдореЙрдбрд▓ рдореЗрдВ рджреЛ рд╕рдВрдЧреНрд░рд╣реЛрдВ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреЛ ToObservableChangeSet рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рджреВрд╕рд░реЗ рдХреЛ ReadOnlyObservableCollection рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ ToObservableChangeSet рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬреЛ Connect рдХреЗ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди ToObservableChangeSet рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

 //   . ReadOnlyObservableCollection<TradeVm> _derived; //    -. var source = new ObservableCollectionExtended<Trade>(); source.ToObservableChangeSet(trade => trade.Key) .Transform(trade => new TradeProxy(trade)) .Filter(proxy => proxy.IsChecked) .Bind(out _derived) .Subscribe(); 

рдбрд╛рдпрдирд╛рдореЗрдЯрд╛рдбрд╛ рдЙрди рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рдЯреНрд░реИрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ рдЬреЛ INotifyPropertyChanged рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рд╕рдВрдЧреНрд░рд╣ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕реВрдЪрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрдм рднреА рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИ, рддреЛ AutoRefresh рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рд╡рд╛рдВрдЫрд┐рдд рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдЪрдпрдирдХрд░реНрддрд╛ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВред AutoRefesh рдФрд░ рдЕрдиреНрдп AutoRefesh рдСрдкрд░реЗрдЯрд░ рдЖрдкрдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рд░реВрдкреЛрдВ рдФрд░ рдЙрдк-рд░реВрдкреЛрдВ рдХреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВрдЧреЗ!

 //  IObservable<bool> var isValid = databases .ToObservableChangeSet() //      IsValid. .AutoRefresh(database => database.IsValid) //       . .ToCollection() // ,    . .Select(x => x.All(y => y.IsValid)); //   ReactiveUI, IObservable<bool> //     ObservableAsProperty. _isValid = isValid .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.IsValid); 

рдбрд╛рдпрдирд╛рдореИрдбрд╛рдЯрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрдк рдЬрд▓реНрджреА рд╕реЗ рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рдЗрдВрдЯрд░рдлреЗрд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ - рдпрд╣ рдЙрди рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдЪ рд╣реИ рдЬреЛ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдбреЗрдЯрд╛, рдЗрдВрд╕реНрдЯреЗрдВрдЯ рдореИрд╕реЗрдЬрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдФрд░ рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред



рдирд┐рд╖реНрдХрд░реНрд╖


рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдШреЛрд╖рдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдкреЛрд░реНрдЯреЗрдмрд▓ рдФрд░ рд╕рдорд░реНрдерд┐рдд рдХреЛрдб рд▓рд┐рдЦрддрд╛ рд╣реИ, рдФрд░ рд╕рд░рд▓ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рддрд░реАрдХреЗ рд╕реЗ рдЬрдЯрд┐рд▓ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИред ReactiveUI .NET рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ INotifyCollectionChanged рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рдХреЗ MVVM рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдмрд╛рд░реАрдХреА рд╕реЗ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ INotifyCollectionChanged рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рд╕рдВрдЧреНрд░рд╣ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХрд╛ рдзреНрдпрд╛рди INotifyCollectionChanged , рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХреА рджреЗрдЦрднрд╛рд▓ рдХрд░рддрд╛ рд╣реИред

ReactiveUI рдФрд░ DynamicData рд▓рд╛рдЗрдмреНрд░реЗрд░реА .NET рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдХреЗ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп GUI рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИрдВ , рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рди рдлрд╛рдЙрдВрдбреЗрд╢рди, рдпреВрдирд┐рд╡рд░реНрд╕рд▓ рд╡рд┐рдВрдбреЛрдЬ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо, рдПрд╡рд▓реЛрдирд┐рдпрд╛, рдЬрд╝рд╛рдорд░реАрдиред рдПрдВрдбреНрд░реЙрдЗрдб, рдЬрд╝рдорд╛рд░рд┐рди рдлреЙрд░реНрдореНрд╕, рдЬрд╝реИрдорд╛рд░рд┐рди рдЖрдИрдУрдПрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЖрдк рд╕рдВрдмрдВрдзрд┐рдд ReactiveUI рдкреНрд░рд▓реЗрдЦрди рдкреГрд╖реНрда рд╕реЗ рдбрд╛рдпрдирд╛рдореИрдЯрдбрд╛рдЯрд╛ рд╕реАрдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдбрд╛рдпрдиреЗрдорд╛рдбрд╛рдЯрд╛ рд╕реНрдирд┐рдкреЗрдЯреНрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдЕрд╡рд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдбрд╛рдпрдирд╛рдореИрдбреИрдЯрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред

Source: https://habr.com/ru/post/hi445098/


All Articles