{"id":15597509,"url":"https://github.com/flagbug/rxui-design-guidelines","last_synced_at":"2026-01-17T22:16:10.476Z","repository":{"id":19413997,"uuid":"22656193","full_name":"flagbug/rxui-design-guidelines","owner":"flagbug","description":"A set of practices to help maintain sanity when building an RxUI client application distilled from hard lessons learned.","archived":false,"fork":false,"pushed_at":"2014-08-05T20:36:00.000Z","size":103,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T12:49:35.170Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flagbug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-05T19:16:51.000Z","updated_at":"2020-10-23T09:23:10.000Z","dependencies_parsed_at":"2022-09-03T04:42:34.032Z","dependency_job_id":null,"html_url":"https://github.com/flagbug/rxui-design-guidelines","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flagbug/rxui-design-guidelines","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagbug%2Frxui-design-guidelines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagbug%2Frxui-design-guidelines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagbug%2Frxui-design-guidelines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagbug%2Frxui-design-guidelines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flagbug","download_url":"https://codeload.github.com/flagbug/rxui-design-guidelines/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagbug%2Frxui-design-guidelines/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28519880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T01:22:11.863Z","updated_at":"2026-01-17T22:16:10.462Z","avatar_url":"https://github.com/flagbug.png","language":null,"readme":"RxUi Design Guidelines\n======================\n\nA set of practices to help maintain sanity when building an RxUI client \napplication distilled from hard lessons learned.\n\n## Best Practices\n\nThe following recommendations are intended to help keep ReactiveUI code \npredictable, understandable, and fast.\n\nThey are, however, only guidelines. Use best judgment when determining whether \nto apply the recommendations here to a given piece of code.\n\n### Commands\n\nPrefer binding user interactions to commands rather than methods.\n\n__Do__\n\n```csharp\n// In XAML\n\u003cButton Command=\"{Binding DeleteCommand}\" .../\u003e\n\npublic class RepositoryViewModel : ViewModelBase \n{\n  public RepositoryViewModel() \n  {\n    DeleteCommand = new ReactiveAsyncCommand();\n    DeleteCommand.RegisterAsyncObservable(\n      x =\u003e Delete(),  \n      e =\u003e /* Do something with error */)\n    .Subscribe();\n  }\n\n  public ReactiveAsyncCommand DeleteCommand { get; private set; }\n\n  public IObservable\u003cUnit\u003e Delete() {...}\n}\n```\n\n__Don't__\n\nUse the Caliburn.Micro conventions for associating buttons and commands:\n\n```csharp\n// In XAML\n\u003cButton x:Name=\"Delete\" .../\u003e\n\npublic class RepositoryViewModel : PropertyChangedBase\n{\n  public void Delete() {...}\t\n}\n```\n\nWhy? \n\n1. ReactiveAsyncCommand exposes the `CanExecute` property of the command to \nenable applications to introduce additional behaviour.\n2. It handles marshaling the result back to the UI thread.\n3. It tracks in-flight items.\n\n\n#### Command Names\n\nDon't suffix `ReactiveCommand` properties' names with `Command`; instead, name the property using a verb that describes the command's action. For example:\n\n```csharp\n\t\npublic IReactiveCommand Synchronize { get; private set; }\n\n// and then in the ctor:\n\nSynchronize = new ReactiveCommand();\nSynchronize.RegisterAsync(_ =\u003e SynchronizeImpl(mergeInsteadOfRebase: !IsAhead))\n    .Subscribe();\n\n```\n\nWhen a `ReactiveCommand`'s implementation is too large or too complex for an anonymous delegate, name the implementation's method the same name as the command, but with `Impl` suffixed (for example, `SychronizeImpl` above).\n\n### UI Thread and Schedulers\n\nAlways make sure to update the UI on the `RxApp.DeferredScheduler` to ensure UI \nchanges happen on the UI thread. In practice, this typically means making sure \nto update view models on the deferred scheduler.\n\n__Do__\n\n```csharp\n.FetchStuffAsync()\n.ObserveOn(RxApp.DeferredScheduler)\n.Subscribe(x =\u003e this.SomeViewModelProperty = x);\n```\n__Don't__\n\n```csharp\n.FetchStuffAsync()\n.Subscribe(x =\u003e this.SomeViewModelProperty = x);\n```\n\nEven better, pass in the scheduler to methods that take one in.\n\n__Better__\n\n```csharp\n.FetchStuffAsync(RxApp.DeferredScheduler)\n.Subscribe(x =\u003e this.SomeViewModelProperty = x);\n```\n\n### Prefer Observable Property Helpers to setting properties explicitly\n\nWhen a property's value depends on another property, a set of properties, or an \nobservable stream, rather than set the value explicitly, use \n`ObservableAsPropertyHelper` with `WhenAny` wherever possible.\n\n__Do__\n\n```csharp\npublic class RepositoryViewModel : ViewModelBase \n{\n  ObservableAsPropertyHelper\u003cbool\u003e canDoIt;\n\n  public RepositoryViewModel() \n  {\n    someViewModelProperty = this.WhenAny(x =\u003e x.StuffFetched, \n\t\t\t\t\t\t\t\t\t y =\u003e y.OtherStuffNotBusy, \n\t\t\t\t\t\t\t\t\t (x, y) =\u003e x \u0026\u0026 y)\n      .ToProperty(this, x =\u003e x.CanDoIt, setViaReflection: false);\n  }\n\n  public bool CanDoIt\n  {\n    get { return canDoIt.Value; }  \n  }\t\n}\n```\n\n__Don't__\n\n```csharp\n.FetchStuffAsync()\n.ObserveOn(RxApp.DeferredScheduler)\n.Subscribe(x =\u003e this.SomeViewModelProperty = x);\n```\n\n### Prefer using `this` as the left hand side of a `WhenAny` call.\n\n__Do__\n\n```csharp\nIDependency dependency;\npublic IDependency Dependency\n{\n  get { return this.dependency; }\n  set { this.RaiseAndSetIfChanged(ref dependency, value); }\n}\n\nIObservableAsPropertyHelper\u003cIStuff\u003e stuff;\n\npublic IStuff Stuff\n{\n  get { return this.stuff.Value; }\n}\n\npublic class MyViewModel(IDependency dependency)\n{\n  Ensure.ArgumentNotNull(dependency, \"dependency\");\n  \n  this.Dependency = dependency;\n  \n  this.stuff = this.WhenAny(x =\u003e x.Dependency.Stuff, x =\u003e x.Value)\n    .ToProperty(this, x =\u003e x.Stuff);\n}\n```\n\n__Don't__\n\n```csharp\npublic class MyViewModel(IDependency dependency)\n{\n  stuff = dependency.WhenAny(x =\u003e x.Stuff, x =\u003e x.Value)\n    .ToProperty(this, x =\u003e x.Stuff);\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflagbug%2Frxui-design-guidelines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflagbug%2Frxui-design-guidelines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflagbug%2Frxui-design-guidelines/lists"}