Причиной проблемы является то, что было выделено @flq.Вы делаете асинхронный вызов , что означает, что вы не получите ожидаемый результат сразу (в вашем случае назначается UserId), но вместо этого вы можете подписаться на событие Completed
(или обеспечить обратный вызов), чтобы обрабатывать вещи, когда асинхронная задача завершается.
Теперь «MVVM-способ» сделать это (или, по крайней мере, то, что я хотел бы сделать) заключается в следующем: во-первых, иди, получи MVVMСвет!это легковесная структура MVVM, которая была бы очень полезна.Вы должны иметь свой класс ViewModel, реализующий базовый класс ViewModelBase
из MVVMLight, это обеспечит уведомление об изменениях и обмен сообщениями, а также другие полезные вещи.Затем вы должны инкапсулировать функциональность входа в команду, чтобы иметь возможность подключить ее из xaml, для этого вы можете использовать MVVMLight's RelayCommand
.Как только вход в систему завершен, вы можете просто отправить сообщение вашему представлению, сообщив ему об этом (довольно несвязно), и представление может просто инициировать навигацию.
Вотбиты кода для этого:
public class LogOnViewModel : ViewModelBase
{
private SHAServiceClient WS;
public LogOnViewModel()
{
WS = new SHAServiceClient();
WS.UserLoginCompleted += new EventHandler<UserLoginCompletedEventArgs>(WS_UserLoginCompleted);
LoginCommand = new RelayCommand(UserLogin);
}
private int userId;
public int UserId
{
get { return userId; }
set
{
userId = value;
RaisePropertyChanged(()=>UserId);
}
}
private int password;
public int Password
{
get { return password; }
set
{
password = value;
RaisePropertyChanged(()=>Password);
}
}
private int username;
public int Username
{
get { return username; }
set
{
username = value;
RaisePropertyChanged(()=>Username);
}
}
private int loginErrorMessage;
public int LoginErrorMessage
{
get { return loginErrorMessage; }
set
{
loginErrorMessage = value;
RaisePropertyChanged(()=>LoginErrorMessage);
}
}
void WS_UserLoginCompleted(object sender, UserLoginCompletedEventArgs e)
{
if (e.Error == null)
{
this.UserId = e.Result;
// send a message to indicate that the login operation has completed
Messenger.Default.Send(new LoginCompleteMessage());
}
}
public RelayCommand LoginCommand {get; private set;}
void UserLogin()
{
WS.UserLoginAsync(email, password);
}
}
для xaml:
<TextBox Text="{Binding Username, Mode=TwoWay}"/>
<TextBox Text="{Binding Password, Mode=TwoWay}"/>
<Button Command="{Binding LoginCommand}"/>
<TextBlock Text="{Binding LoginErrorMessage}"/>
в коде:
public partial class LogOn : PhoneApplicationPage
{
public LogOn()
{
InitializeComponent();
this.DataContext = new LogOnViewModel();
Messenger.Default.Register<LoginCompletedMessage>(
this,
msg=> NavigationService.Navigate(
new Uri("/_2HandApp;component/Views/Main.xaml",
UriKind.Relative) );
}
....
}
Вы можете видеть, что есть немногонемного больше (но простой) код в ViewModel и меньше в коде позади.Это также использовало преимущества DataBinding, которая лежит в основе MVVM.
Надеюсь, что это поможет:)
PS: класс LoginCompletedMessage в данном случае является просто пустым классом(используется только для определения типа сообщения), но вы можете использовать его для отправки дополнительной информации (возможно, вам все еще нужно отправить UserId)