2017-02-20 31 views
1

Хорошо, прежде чем вы что-нибудь скажете, я знаю, что несколько сообщений этого существуют, и я ищу ответ часами. Я новый пользователь в Stack Overflow и довольно новичок в C# и UWP, поэтому, пожалуйста, не стесняйтесь меня исправлять.PropertyChanged is Null UWP

Я делаю приложение хранилища UWP для Windows 10. Я использую API и подключаюсь к серверу. Все это происходит на отдельной странице моего MainPage.xaml, которая загружается в Frame!

То, что я хочу сделать, это показать string connectionStatus к MainPage.xaml (через <TextBlock/>) в то время как она меняется в моем LoginPage.xaml.cs (который находится внутри MainPage.xaml кадра). Я использую INotifyPropertyChanged. Если какой-либо из этих вопросов не имеет смысла, напишите комментарий, и я постараюсь ответить.

Так что я в моем MainPage.xaml этот код для связывания и <Page.DataContext> для NotifyChanges класса (который в моем LoginPage.xaml.cs).

<Page.DataContext> 
    <local:NotifyChanges/> 
</Page.DataContext> 

<TextBlock Text="{Binding ConnectionStatus, Mode=OneWay}" Margin="0,0,10,0" Foreground="LimeGreen" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Right" FontSize="18"/> 

А вот мой NotifyChanges класс, который находится в моем LoginPage.xaml.cs, который загружается внутри Frame в моем MainPage.xaml:

public class NotifyChanges : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    // This method is called by the Set accessor of each property. 
    // The CallerMemberName attribute that is applied to the optional propertyName 
    // parameter causes the property name of the caller to be substituted as an argument. 
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private string connectionStatus = "Disconnected"; 

    public string ConnectionStatus 
    { 
     get 
     { 
      return connectionStatus; 
     } 

     set 
     { 
      if (value != connectionStatus) 
      { 
       connectionStatus = value; 
       NotifyPropertyChanged("ConnectionStatus"); 
      } 
     } 
    } 
} 

Последнее, но не менее, вот мой код, который изменяет connectionStatus в два в разных местах, при подключении и после подключения.

public async Task Run() 
{ 
    NotifyChanges notifyChanges = new NotifyChanges(); 

    try 
    { 
     userToken = TokenTextBox.Text; 

     await client.LoginAsync(TokenType.User, userToken); 

     var connect = client.ConnectAsync(); 

     notifyChanges.ConnectionStatus = client.ConnectionState.ToString(); 

     await connect; 

     notifyChanges.ConnectionStatus = client.ConnectionState.ToString(); 

     Frame.Navigate(typeof(ChatPage), userToken); 

     // Block this task until the program is exited. 
     await Task.Delay(-1); 
    } 
    catch 
    { 
     ConnectionErrorTextBlock.Text = "Something went wrong :/ You may want to check the token again!"; 
    } 
} 

Примечания: Связывание, кажется, работает, потому что, как вы можете видеть, я установить значение по умолчанию «Disconected» и он установлен, но после того, что он никогда не меняется. Я отлаживал программу, и приложение входит в определение NotifyChanges, но никогда не выполняет событие уведомления, потому что PropertyChanged никогда не изменяется от Null. Я что-то упустил? Моя ошибка в другом месте? Заранее спасибо!

ответ

1

Да, вы упускаете что-то - это пайса кода:

<Page.DataContext> 
    <local:NotifyChanges/> 
</Page.DataContext> 

и это одна:

NotifyChanges notifyChanges = new NotifyChanges(); 

создать две разные ссылки. Когда вы работаете с привязкой, вы хотите работать с одной и той же ссылкой класса. Если ваш метод Run() указан на этой странице, это может сработать:

public async Task Run() 
{ 
    NotifyChanges notifyChanges = this.DataContext as NotifyChanges; 
    // rest of the code 
+0

Это работает. Спасибо, мужик. Пробывали это часами. Не могли бы вы объяснить, почему это происходит? Этот.DataContext указывает на ту же страницу, что и Login.xaml.cs. Связывание происходит на странице MainPage. Как это работает ? Спасибо! – KonKarapas

+0

@KonKarapas Связывание относится только к классу из DataContext, который в вашем случае был создан в xaml. В вашем решении, в методе «Выполнить», вы создали совершенно новую ссылку, которую вы модифицировали, но это не та, которая связана с данными. Пользовательский интерфейс связан с созданным в xaml. – Romasz

+0

@KonKarapas Обратите внимание, что вы также можете назначить * NotifyChanges * в конструкторе страницы подходящему свойству, а затем установить 'this.DataContext = propertyNotifyChanges;' - тогда у вас есть свойство в коде, которое вы можете легко изменить без каста/создания (нет необходимости для установки DataContext в xaml).Вы также можете использовать 'x: Bind', не задавая * DataContext *, но это другая история - есть много блогов/сообщений об этом. – Romasz