问题
So I have been trying to get guard clauses to work with Caliburn.Micro and a bound textbox.
The View:
<TextBox x:Name="UserAccount_DisplayName" Margin="-10,-5,-10,8"/>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="False">
<shell:ApplicationBar.Buttons>
<cal:AppBarButton IconUri="\Resources\Iconography\appbar.check.rest.png"
Text="Save"
Message="SaveAndNavigateToAddAccountView" />
</shell:ApplicationBar.Buttons>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
The ViewModel:
public class EditAccountNameViewModel: PropertyChangedBase
public Account UserAccount
{
get
{
return account;
}
set
{
account = value;
NotifyOfPropertyChange(() => UserAccount);
NotifyOfPropertyChange(() => CanSaveAndNavigateToAddAccountView);
}
}
public bool CanSaveAndNavigateToAddAccountView
{
get
{
if (string.IsNullOrEmpty(UserAccount.DisplayName) == true)
{
return false;
}
return true;
}
}
public void SaveAndNavigateToAddAccountView()
{
CommitAccountToStorage();
navigationService.UriFor<AddAccountViewModel>().Navigate();
}
For some reason the guard clause is not firing after I begin typing in the textbox, which is what I would have assumed should happen. Any ideas?
回答1:
Does the guard clause fire when you type something in the textbox and then select another element (so that textbox loses focus)? If so, try simulating UpdateSourceTrigger=PropertyChanged setting of a binding. See anwsers to "UpdateSourceTrigger=PropertyChanged" equivalent for a Windows Phone 7 TextBox to see how to simulate this behavior.
EDIT: I see, that you are binding (by convention) to a "DisplayName" property of UserAccount. This means, that setter of EditAccountNameViewModel.UserAccount property will not be called when you type something in the textbox. Instead, a setter on UserAccount.DisplayName will be called. What I'd suggest you to do is to create another property in your ViewModel, say UserAccountDisplayName, that would look sth like this, and bind to it instead:
public string UserAccountDisplayName
{
get { return UserAccount.DisplayName; }
set
{
UserAccount.DisplayName = value;
NotifyOfPropertyChange(() => UserAccountDisplayName);
NotifyOfPropertyChange(() => CanSaveAndNavigateToAddAccountView);
}
}
This + simulating PropertyChanged trigger should work.
来源:https://stackoverflow.com/questions/6720196/guard-clause-not-firing