ReactiveCommand with combined criteria for CanExecute
I have just started with ReactiveUI. I have the following class:
public class MainViewModel : ReactiveObject, IRoutableViewModel
{
private string shareText;
public ReactiveCollection<SharingAccountViewModel> SelectedAccounts { get; private set; }
public string ShareText
{
get { return shareText; }
set
{
this.RaiseAndSetIfChanged(ref shareText, value);
}
}
public IReactiveCommand ShareCommand { get; private set; }
}
What I would like to do is to be allow the command to execute when the following criteria is true:
- The ShareText property is not null or empty
- The SelectedAccounts collection contains at least one value
I have tried the following but it does not work as the button which is hooked up to the command never gets enabled:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
viewModel => viewModel.SelectedAccounts,
(x, y) => !String.IsNullOrEmpty(x.Value) && y.Value.Count > 0));
If I just check for the ShareText property however, it works fine:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
(x) => !String.IsNullOrEmpty(x.Value)));
I looked at the answer for the question ReactiveUI: Using CanExecute with a ReactiveCommand
Based on that I tried the following:
var accountsSelected = SelectedAccounts.CollectionCountChanged.Select(count => count > 0);
ShareCommand = new ReactiveCommand(accountsSelected);
This is working for the second part of my execution criteria because as soon as items are added or removed from the collection, the button which is hooked up to the command gets enabled or disabled correctly.
My question is how do I now combine that with checking that the ShareText property is not null or empty?
I cannot use the this.WhenAny(..) method anymore as the accountsSelected variable is not a property.
Thanks
c# system.reactive reactiveui
add a comment |
I have just started with ReactiveUI. I have the following class:
public class MainViewModel : ReactiveObject, IRoutableViewModel
{
private string shareText;
public ReactiveCollection<SharingAccountViewModel> SelectedAccounts { get; private set; }
public string ShareText
{
get { return shareText; }
set
{
this.RaiseAndSetIfChanged(ref shareText, value);
}
}
public IReactiveCommand ShareCommand { get; private set; }
}
What I would like to do is to be allow the command to execute when the following criteria is true:
- The ShareText property is not null or empty
- The SelectedAccounts collection contains at least one value
I have tried the following but it does not work as the button which is hooked up to the command never gets enabled:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
viewModel => viewModel.SelectedAccounts,
(x, y) => !String.IsNullOrEmpty(x.Value) && y.Value.Count > 0));
If I just check for the ShareText property however, it works fine:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
(x) => !String.IsNullOrEmpty(x.Value)));
I looked at the answer for the question ReactiveUI: Using CanExecute with a ReactiveCommand
Based on that I tried the following:
var accountsSelected = SelectedAccounts.CollectionCountChanged.Select(count => count > 0);
ShareCommand = new ReactiveCommand(accountsSelected);
This is working for the second part of my execution criteria because as soon as items are added or removed from the collection, the button which is hooked up to the command gets enabled or disabled correctly.
My question is how do I now combine that with checking that the ShareText property is not null or empty?
I cannot use the this.WhenAny(..) method anymore as the accountsSelected variable is not a property.
Thanks
c# system.reactive reactiveui
add a comment |
I have just started with ReactiveUI. I have the following class:
public class MainViewModel : ReactiveObject, IRoutableViewModel
{
private string shareText;
public ReactiveCollection<SharingAccountViewModel> SelectedAccounts { get; private set; }
public string ShareText
{
get { return shareText; }
set
{
this.RaiseAndSetIfChanged(ref shareText, value);
}
}
public IReactiveCommand ShareCommand { get; private set; }
}
What I would like to do is to be allow the command to execute when the following criteria is true:
- The ShareText property is not null or empty
- The SelectedAccounts collection contains at least one value
I have tried the following but it does not work as the button which is hooked up to the command never gets enabled:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
viewModel => viewModel.SelectedAccounts,
(x, y) => !String.IsNullOrEmpty(x.Value) && y.Value.Count > 0));
If I just check for the ShareText property however, it works fine:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
(x) => !String.IsNullOrEmpty(x.Value)));
I looked at the answer for the question ReactiveUI: Using CanExecute with a ReactiveCommand
Based on that I tried the following:
var accountsSelected = SelectedAccounts.CollectionCountChanged.Select(count => count > 0);
ShareCommand = new ReactiveCommand(accountsSelected);
This is working for the second part of my execution criteria because as soon as items are added or removed from the collection, the button which is hooked up to the command gets enabled or disabled correctly.
My question is how do I now combine that with checking that the ShareText property is not null or empty?
I cannot use the this.WhenAny(..) method anymore as the accountsSelected variable is not a property.
Thanks
c# system.reactive reactiveui
I have just started with ReactiveUI. I have the following class:
public class MainViewModel : ReactiveObject, IRoutableViewModel
{
private string shareText;
public ReactiveCollection<SharingAccountViewModel> SelectedAccounts { get; private set; }
public string ShareText
{
get { return shareText; }
set
{
this.RaiseAndSetIfChanged(ref shareText, value);
}
}
public IReactiveCommand ShareCommand { get; private set; }
}
What I would like to do is to be allow the command to execute when the following criteria is true:
- The ShareText property is not null or empty
- The SelectedAccounts collection contains at least one value
I have tried the following but it does not work as the button which is hooked up to the command never gets enabled:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
viewModel => viewModel.SelectedAccounts,
(x, y) => !String.IsNullOrEmpty(x.Value) && y.Value.Count > 0));
If I just check for the ShareText property however, it works fine:
ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
(x) => !String.IsNullOrEmpty(x.Value)));
I looked at the answer for the question ReactiveUI: Using CanExecute with a ReactiveCommand
Based on that I tried the following:
var accountsSelected = SelectedAccounts.CollectionCountChanged.Select(count => count > 0);
ShareCommand = new ReactiveCommand(accountsSelected);
This is working for the second part of my execution criteria because as soon as items are added or removed from the collection, the button which is hooked up to the command gets enabled or disabled correctly.
My question is how do I now combine that with checking that the ShareText property is not null or empty?
I cannot use the this.WhenAny(..) method anymore as the accountsSelected variable is not a property.
Thanks
c# system.reactive reactiveui
c# system.reactive reactiveui
edited Jan 1 at 13:17
Askolein
1,94011731
1,94011731
asked Mar 18 '13 at 10:03
Jerrie PelserJerrie Pelser
423714
423714
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Using WhenAny with an IObservable
is a bit tricky. Here's how I would do it:
var canShare = Observable.CombineLatest(
this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
this.WhenAny(x => x.ShareText, x => x.Value),
(count, text) => count > 0 && !String.IsNullOrWhitespace(text));
The advantage of WhenAnyObservable
here, is that if you decided to reassign SelectedAccounts (i.e. SelectedAccounts = new ReactiveCollection(...);
, the above statement would still work, whereas the one above would still be listening to the old collection.
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
add a comment |
I believe that there are different ways to get the expected result and this is just one way.
var canExecute = this.ObservableForProperty(v => v.ShareText)
.Select(_ => Unit.Default)
.Merge(SelectedAccounts.CollectionCountChanged
.Select(_ => Unit.Default))
.Select(_ => !String.IsNullOrEmpty(ShareText)
&& SelectedAccounts.Any())
.StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15474043%2freactivecommand-with-combined-criteria-for-canexecute%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Using WhenAny with an IObservable
is a bit tricky. Here's how I would do it:
var canShare = Observable.CombineLatest(
this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
this.WhenAny(x => x.ShareText, x => x.Value),
(count, text) => count > 0 && !String.IsNullOrWhitespace(text));
The advantage of WhenAnyObservable
here, is that if you decided to reassign SelectedAccounts (i.e. SelectedAccounts = new ReactiveCollection(...);
, the above statement would still work, whereas the one above would still be listening to the old collection.
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
add a comment |
Using WhenAny with an IObservable
is a bit tricky. Here's how I would do it:
var canShare = Observable.CombineLatest(
this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
this.WhenAny(x => x.ShareText, x => x.Value),
(count, text) => count > 0 && !String.IsNullOrWhitespace(text));
The advantage of WhenAnyObservable
here, is that if you decided to reassign SelectedAccounts (i.e. SelectedAccounts = new ReactiveCollection(...);
, the above statement would still work, whereas the one above would still be listening to the old collection.
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
add a comment |
Using WhenAny with an IObservable
is a bit tricky. Here's how I would do it:
var canShare = Observable.CombineLatest(
this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
this.WhenAny(x => x.ShareText, x => x.Value),
(count, text) => count > 0 && !String.IsNullOrWhitespace(text));
The advantage of WhenAnyObservable
here, is that if you decided to reassign SelectedAccounts (i.e. SelectedAccounts = new ReactiveCollection(...);
, the above statement would still work, whereas the one above would still be listening to the old collection.
Using WhenAny with an IObservable
is a bit tricky. Here's how I would do it:
var canShare = Observable.CombineLatest(
this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
this.WhenAny(x => x.ShareText, x => x.Value),
(count, text) => count > 0 && !String.IsNullOrWhitespace(text));
The advantage of WhenAnyObservable
here, is that if you decided to reassign SelectedAccounts (i.e. SelectedAccounts = new ReactiveCollection(...);
, the above statement would still work, whereas the one above would still be listening to the old collection.
answered Mar 19 '13 at 1:42
Paul BettsPaul Betts
64.7k15116190
64.7k15116190
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
add a comment |
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
Thank you Paul. I like your solution as it is more compact and slightly easier for me to understand. Trying to get my head around Rx... Loving your work on ReactiveUI btw
– Jerrie Pelser
Mar 19 '13 at 4:10
add a comment |
I believe that there are different ways to get the expected result and this is just one way.
var canExecute = this.ObservableForProperty(v => v.ShareText)
.Select(_ => Unit.Default)
.Merge(SelectedAccounts.CollectionCountChanged
.Select(_ => Unit.Default))
.Select(_ => !String.IsNullOrEmpty(ShareText)
&& SelectedAccounts.Any())
.StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
add a comment |
I believe that there are different ways to get the expected result and this is just one way.
var canExecute = this.ObservableForProperty(v => v.ShareText)
.Select(_ => Unit.Default)
.Merge(SelectedAccounts.CollectionCountChanged
.Select(_ => Unit.Default))
.Select(_ => !String.IsNullOrEmpty(ShareText)
&& SelectedAccounts.Any())
.StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
add a comment |
I believe that there are different ways to get the expected result and this is just one way.
var canExecute = this.ObservableForProperty(v => v.ShareText)
.Select(_ => Unit.Default)
.Merge(SelectedAccounts.CollectionCountChanged
.Select(_ => Unit.Default))
.Select(_ => !String.IsNullOrEmpty(ShareText)
&& SelectedAccounts.Any())
.StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);
I believe that there are different ways to get the expected result and this is just one way.
var canExecute = this.ObservableForProperty(v => v.ShareText)
.Select(_ => Unit.Default)
.Merge(SelectedAccounts.CollectionCountChanged
.Select(_ => Unit.Default))
.Select(_ => !String.IsNullOrEmpty(ShareText)
&& SelectedAccounts.Any())
.StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);
edited Mar 18 '13 at 22:14
answered Mar 18 '13 at 21:27
Doug MitchellDoug Mitchell
16218
16218
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
add a comment |
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
Works like a charm, thanks!
– Jerrie Pelser
Mar 19 '13 at 0:25
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15474043%2freactivecommand-with-combined-criteria-for-canexecute%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown