A ViewModel build with ReactiveUI 8 to get web images
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
This is a practice application that I built to learn Rx.Net & RxUI. It follows the MVVM pattern and is written in C# with WPF. Here is a link to a question I asked during the development, which includes some information about this application. Now that it finally runs, I want to improve it by eliminating any potential flaws in the code, which is presented as follows:
public class MainViewModel : ReactiveObject
#region Constructors
public MainViewModel()
_currentState = new BehaviorSubject<MainViewModelState>(MainViewModelState.Idle);
_status = _currentState.Select(s => s.ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Status));
_progress = _currentState.Select(s => ((int) s).ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Progress));
var canSearch = this.WhenAnyValue(x => x.TargetUrl, x => !string.IsNullOrEmpty(x))
.CombineLatest(_currentState, (b, state) => b && _currentState.Value == MainViewModelState.Idle);
_searchCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.FetchingHtmlDoc);
return TargetUrl;
, canSearch);
_searchCommand.SelectMany(HtmlDownloadService.GetHtmlDocument)
.Zip(_searchCommand, Tuple.Create)
.Do(_ => _currentState.OnNext(MainViewModelState.ExtractingImageUrl))
.Select(tuple => ImageExtractService.ExtractAllImageAddress(tuple.Item1, tuple.Item2).Distinct())
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(
urls =>
_currentState.OnNext(MainViewModelState.PopulatingList);
urls.ToObservable().ObserveOn(RxApp.MainThreadScheduler).Subscribe(url =>
ImageList.Add(new ScrappedWebImageViewModel ImageUrl = url));
_currentState.OnNext(MainViewModelState.Idle);
,
ex => this.Log().Error(ex));
var canClear = _currentState.Select(x => x == MainViewModelState.Idle).ObserveOn(RxApp.MainThreadScheduler);
_clearCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.ClearingList);
ImageList.Clear();
_currentState.OnNext(MainViewModelState.Idle);
, canClear, RxApp.MainThreadScheduler);
#endregion
#region Properties
private IHtmlDownloadService _htmlDownloadService;
private IHtmlDownloadService HtmlDownloadService =>
_htmlDownloadService ?? (_htmlDownloadService = Locator.Current.GetService<IHtmlDownloadService>());
private IImageExtractService _imageExtractService;
private IImageExtractService ImageExtractService =>
_imageExtractService ?? (_imageExtractService = Locator.Current.GetService<IImageExtractService>());
private readonly BehaviorSubject<MainViewModelState> _currentState;
public ReactiveList<ScrappedWebImageViewModel> ImageList =
new ReactiveList<ScrappedWebImageViewModel>();
private readonly ObservableAsPropertyHelper<string> _status;
public string Status => _status.Value;
private readonly ObservableAsPropertyHelper<string> _progress;
public string Progress => _progress.Value;
private string _targetUrl;
public string TargetUrl
get => _targetUrl;
set => this.RaiseAndSetIfChanged(ref _targetUrl, value);
#endregion
#region Commands
private readonly ReactiveCommand<Unit, string> _searchCommand;
public ICommand SearchCommand => _searchCommand;
private readonly ReactiveCommand<Unit, Unit> _clearCommand;
public ICommand ClearCommand => _clearCommand;
#endregion
#region Methods
#endregion
#region Types
private enum MainViewModelState
Idle = 0,
FetchingHtmlDoc,
ExtractingImageUrl,
PopulatingList,
ClearingList
#endregion
During my test runs, I noticed that when extracting Urls, the UI became unresponsive, but I can't figure out a better way to do it. Also I wish to add cancellation functionalities but it seems quite difficult to implement with the current code, perhaps I'm not following the best practice?
c# wpf mvvm system.reactive
add a comment |Â
up vote
1
down vote
favorite
This is a practice application that I built to learn Rx.Net & RxUI. It follows the MVVM pattern and is written in C# with WPF. Here is a link to a question I asked during the development, which includes some information about this application. Now that it finally runs, I want to improve it by eliminating any potential flaws in the code, which is presented as follows:
public class MainViewModel : ReactiveObject
#region Constructors
public MainViewModel()
_currentState = new BehaviorSubject<MainViewModelState>(MainViewModelState.Idle);
_status = _currentState.Select(s => s.ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Status));
_progress = _currentState.Select(s => ((int) s).ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Progress));
var canSearch = this.WhenAnyValue(x => x.TargetUrl, x => !string.IsNullOrEmpty(x))
.CombineLatest(_currentState, (b, state) => b && _currentState.Value == MainViewModelState.Idle);
_searchCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.FetchingHtmlDoc);
return TargetUrl;
, canSearch);
_searchCommand.SelectMany(HtmlDownloadService.GetHtmlDocument)
.Zip(_searchCommand, Tuple.Create)
.Do(_ => _currentState.OnNext(MainViewModelState.ExtractingImageUrl))
.Select(tuple => ImageExtractService.ExtractAllImageAddress(tuple.Item1, tuple.Item2).Distinct())
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(
urls =>
_currentState.OnNext(MainViewModelState.PopulatingList);
urls.ToObservable().ObserveOn(RxApp.MainThreadScheduler).Subscribe(url =>
ImageList.Add(new ScrappedWebImageViewModel ImageUrl = url));
_currentState.OnNext(MainViewModelState.Idle);
,
ex => this.Log().Error(ex));
var canClear = _currentState.Select(x => x == MainViewModelState.Idle).ObserveOn(RxApp.MainThreadScheduler);
_clearCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.ClearingList);
ImageList.Clear();
_currentState.OnNext(MainViewModelState.Idle);
, canClear, RxApp.MainThreadScheduler);
#endregion
#region Properties
private IHtmlDownloadService _htmlDownloadService;
private IHtmlDownloadService HtmlDownloadService =>
_htmlDownloadService ?? (_htmlDownloadService = Locator.Current.GetService<IHtmlDownloadService>());
private IImageExtractService _imageExtractService;
private IImageExtractService ImageExtractService =>
_imageExtractService ?? (_imageExtractService = Locator.Current.GetService<IImageExtractService>());
private readonly BehaviorSubject<MainViewModelState> _currentState;
public ReactiveList<ScrappedWebImageViewModel> ImageList =
new ReactiveList<ScrappedWebImageViewModel>();
private readonly ObservableAsPropertyHelper<string> _status;
public string Status => _status.Value;
private readonly ObservableAsPropertyHelper<string> _progress;
public string Progress => _progress.Value;
private string _targetUrl;
public string TargetUrl
get => _targetUrl;
set => this.RaiseAndSetIfChanged(ref _targetUrl, value);
#endregion
#region Commands
private readonly ReactiveCommand<Unit, string> _searchCommand;
public ICommand SearchCommand => _searchCommand;
private readonly ReactiveCommand<Unit, Unit> _clearCommand;
public ICommand ClearCommand => _clearCommand;
#endregion
#region Methods
#endregion
#region Types
private enum MainViewModelState
Idle = 0,
FetchingHtmlDoc,
ExtractingImageUrl,
PopulatingList,
ClearingList
#endregion
During my test runs, I noticed that when extracting Urls, the UI became unresponsive, but I can't figure out a better way to do it. Also I wish to add cancellation functionalities but it seems quite difficult to implement with the current code, perhaps I'm not following the best practice?
c# wpf mvvm system.reactive
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
This is a practice application that I built to learn Rx.Net & RxUI. It follows the MVVM pattern and is written in C# with WPF. Here is a link to a question I asked during the development, which includes some information about this application. Now that it finally runs, I want to improve it by eliminating any potential flaws in the code, which is presented as follows:
public class MainViewModel : ReactiveObject
#region Constructors
public MainViewModel()
_currentState = new BehaviorSubject<MainViewModelState>(MainViewModelState.Idle);
_status = _currentState.Select(s => s.ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Status));
_progress = _currentState.Select(s => ((int) s).ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Progress));
var canSearch = this.WhenAnyValue(x => x.TargetUrl, x => !string.IsNullOrEmpty(x))
.CombineLatest(_currentState, (b, state) => b && _currentState.Value == MainViewModelState.Idle);
_searchCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.FetchingHtmlDoc);
return TargetUrl;
, canSearch);
_searchCommand.SelectMany(HtmlDownloadService.GetHtmlDocument)
.Zip(_searchCommand, Tuple.Create)
.Do(_ => _currentState.OnNext(MainViewModelState.ExtractingImageUrl))
.Select(tuple => ImageExtractService.ExtractAllImageAddress(tuple.Item1, tuple.Item2).Distinct())
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(
urls =>
_currentState.OnNext(MainViewModelState.PopulatingList);
urls.ToObservable().ObserveOn(RxApp.MainThreadScheduler).Subscribe(url =>
ImageList.Add(new ScrappedWebImageViewModel ImageUrl = url));
_currentState.OnNext(MainViewModelState.Idle);
,
ex => this.Log().Error(ex));
var canClear = _currentState.Select(x => x == MainViewModelState.Idle).ObserveOn(RxApp.MainThreadScheduler);
_clearCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.ClearingList);
ImageList.Clear();
_currentState.OnNext(MainViewModelState.Idle);
, canClear, RxApp.MainThreadScheduler);
#endregion
#region Properties
private IHtmlDownloadService _htmlDownloadService;
private IHtmlDownloadService HtmlDownloadService =>
_htmlDownloadService ?? (_htmlDownloadService = Locator.Current.GetService<IHtmlDownloadService>());
private IImageExtractService _imageExtractService;
private IImageExtractService ImageExtractService =>
_imageExtractService ?? (_imageExtractService = Locator.Current.GetService<IImageExtractService>());
private readonly BehaviorSubject<MainViewModelState> _currentState;
public ReactiveList<ScrappedWebImageViewModel> ImageList =
new ReactiveList<ScrappedWebImageViewModel>();
private readonly ObservableAsPropertyHelper<string> _status;
public string Status => _status.Value;
private readonly ObservableAsPropertyHelper<string> _progress;
public string Progress => _progress.Value;
private string _targetUrl;
public string TargetUrl
get => _targetUrl;
set => this.RaiseAndSetIfChanged(ref _targetUrl, value);
#endregion
#region Commands
private readonly ReactiveCommand<Unit, string> _searchCommand;
public ICommand SearchCommand => _searchCommand;
private readonly ReactiveCommand<Unit, Unit> _clearCommand;
public ICommand ClearCommand => _clearCommand;
#endregion
#region Methods
#endregion
#region Types
private enum MainViewModelState
Idle = 0,
FetchingHtmlDoc,
ExtractingImageUrl,
PopulatingList,
ClearingList
#endregion
During my test runs, I noticed that when extracting Urls, the UI became unresponsive, but I can't figure out a better way to do it. Also I wish to add cancellation functionalities but it seems quite difficult to implement with the current code, perhaps I'm not following the best practice?
c# wpf mvvm system.reactive
This is a practice application that I built to learn Rx.Net & RxUI. It follows the MVVM pattern and is written in C# with WPF. Here is a link to a question I asked during the development, which includes some information about this application. Now that it finally runs, I want to improve it by eliminating any potential flaws in the code, which is presented as follows:
public class MainViewModel : ReactiveObject
#region Constructors
public MainViewModel()
_currentState = new BehaviorSubject<MainViewModelState>(MainViewModelState.Idle);
_status = _currentState.Select(s => s.ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Status));
_progress = _currentState.Select(s => ((int) s).ToString()).ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(Progress));
var canSearch = this.WhenAnyValue(x => x.TargetUrl, x => !string.IsNullOrEmpty(x))
.CombineLatest(_currentState, (b, state) => b && _currentState.Value == MainViewModelState.Idle);
_searchCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.FetchingHtmlDoc);
return TargetUrl;
, canSearch);
_searchCommand.SelectMany(HtmlDownloadService.GetHtmlDocument)
.Zip(_searchCommand, Tuple.Create)
.Do(_ => _currentState.OnNext(MainViewModelState.ExtractingImageUrl))
.Select(tuple => ImageExtractService.ExtractAllImageAddress(tuple.Item1, tuple.Item2).Distinct())
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(
urls =>
_currentState.OnNext(MainViewModelState.PopulatingList);
urls.ToObservable().ObserveOn(RxApp.MainThreadScheduler).Subscribe(url =>
ImageList.Add(new ScrappedWebImageViewModel ImageUrl = url));
_currentState.OnNext(MainViewModelState.Idle);
,
ex => this.Log().Error(ex));
var canClear = _currentState.Select(x => x == MainViewModelState.Idle).ObserveOn(RxApp.MainThreadScheduler);
_clearCommand = ReactiveCommand.Create(() =>
_currentState.OnNext(MainViewModelState.ClearingList);
ImageList.Clear();
_currentState.OnNext(MainViewModelState.Idle);
, canClear, RxApp.MainThreadScheduler);
#endregion
#region Properties
private IHtmlDownloadService _htmlDownloadService;
private IHtmlDownloadService HtmlDownloadService =>
_htmlDownloadService ?? (_htmlDownloadService = Locator.Current.GetService<IHtmlDownloadService>());
private IImageExtractService _imageExtractService;
private IImageExtractService ImageExtractService =>
_imageExtractService ?? (_imageExtractService = Locator.Current.GetService<IImageExtractService>());
private readonly BehaviorSubject<MainViewModelState> _currentState;
public ReactiveList<ScrappedWebImageViewModel> ImageList =
new ReactiveList<ScrappedWebImageViewModel>();
private readonly ObservableAsPropertyHelper<string> _status;
public string Status => _status.Value;
private readonly ObservableAsPropertyHelper<string> _progress;
public string Progress => _progress.Value;
private string _targetUrl;
public string TargetUrl
get => _targetUrl;
set => this.RaiseAndSetIfChanged(ref _targetUrl, value);
#endregion
#region Commands
private readonly ReactiveCommand<Unit, string> _searchCommand;
public ICommand SearchCommand => _searchCommand;
private readonly ReactiveCommand<Unit, Unit> _clearCommand;
public ICommand ClearCommand => _clearCommand;
#endregion
#region Methods
#endregion
#region Types
private enum MainViewModelState
Idle = 0,
FetchingHtmlDoc,
ExtractingImageUrl,
PopulatingList,
ClearingList
#endregion
During my test runs, I noticed that when extracting Urls, the UI became unresponsive, but I can't figure out a better way to do it. Also I wish to add cancellation functionalities but it seems quite difficult to implement with the current code, perhaps I'm not following the best practice?
c# wpf mvvm system.reactive
asked Feb 8 at 10:25
wuLiao
61
61
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16
add a comment |Â
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187082%2fa-viewmodel-build-with-reactiveui-8-to-get-web-images%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Because we don't deal with code not yet implemented, don't expect someone to show you how to add your cancellation. But it's quite appropriate to ask how changes to your code would make it easier to add that yourself. So your question is welcome here.
â Toby Speight
Feb 8 at 11:16