2016-07-25 3 views
0

Я хочу получить первую запись из таблицы AboutUs и отобразить ее как метку содержимого.Объект не установлен в классе ViewModel, и элемент управления напрямую перемещается из класса доступа к данным в View

Я создал 4 класса в шаблоне MVVM.

первых, это модель AboutUs.cs класса

[Table("tblAboutUs")] 
    public class AboutUs 
    { 
     [PrimaryKey, AutoIncrement, NotNull] 
     public int IDP { get; set; } 
     public string Content { get; set; } 
    } 

Во-вторых, класс доступа к данным

SQLiteAboutUs.cs

public class SQLiteAboutUs 
    { 
     private static readonly AsyncLock Mutex = new AsyncLock(); 
     private SQLiteAsyncConnection dbConn; 

     public int StatusCode { get; set; } 

     public SQLiteAboutUs(ISQLitePlatform sqlitePlatform, string dbPath) 
     { 

      if (dbConn == null) 
      { 
       var connectionFunc = new Func<SQLiteConnectionWithLock>(() => 
        new SQLiteConnectionWithLock 
        (
         sqlitePlatform, 
         new SQLiteConnectionString(dbPath, storeDateTimeAsTicks: false) 
        )); 

       dbConn = new SQLiteAsyncConnection(connectionFunc); 
       dbConn.CreateTableAsync<Model.AboutUs>(); 
      } 
     } 

     public SQLiteAboutUs() 
     { 
     } 
     public async Task Save(Model.AboutUs content) 
     { 
      using (await Mutex.LockAsync().ConfigureAwait(false)) 
      { 
       StatusCode = 0; 


      await dbConn.InsertAsync(new Model.AboutUs { Content = content.Content }); 
      StatusCode = 1; 
     } 

     //For Get first Row from Table 
     public async Task<Model.AboutUs> GetAllData() 
     { 
      return await dbConn.Table<Model.AboutUs>().Where(x => x.IDP == 1).FirstOrDefaultAsync(); 
     } 
    } 

Третий класс ViewModel класса

AboutUsViewModel.cs

public class AboutUsViewModel 
    { 
     readonly SQLiteAboutUs _db; 
     public string AboutUsContent { get; set; } 

     //public string AboutUs; 
     public AboutUsViewModel() 
     { 
      _db = new SQLiteAboutUs(); 
     } 
     public async void FirstRecord() 
     { 
      Model.AboutUs obj = await _db.GetAllData(); 
      this.AboutUsContent = obj.Content; 
     } 
    } 

Forth один код позади файла моих XAML страниц.

AboutUs.xaml.cs

public partial class AboutUs : ContentPage 
    { 
     readonly AboutUsViewModel aboutUsViewModel; 
     public AboutUs() 
     { 
      InitializeComponent(); 

      aboutUsViewModel = new AboutUsViewModel(); 

      aboutUsViewModel.FirstRecord(); 

      lblContent.Text = aboutUsViewModel.AboutUsContent; 
     } 
    } 

У меня есть отладки кода, но проблема заключается в классе AboutUsViewModel.cs в объекте FirstRecord метод не может быть установлен, поэтому AboutUsContent строковое свойство также не установлено ,

Я не могу понять, почему мой отладчик напрямую перескакивает с метода GetAllData() в SQLiteAboutUs.cs на label.text в коде за файлом представления?

+0

Что именно здесь пусто? Вы уверены, что dbConn не является нулевым? Это случалось со мной много раз. можете ли вы также попытаться присвоить такую ​​переменную? var result = wait dbConn.Table (). Где (x => x.IDP == 1) .FirstOrDefaultAsync(); с попыткой поймать, возможно, чтобы убедиться, что FirstOrDefaultAsync создает проблему или возвращает тип проблемы? – batmaci

ответ

1

Добро пожаловать в чудесный мир асинхронности. Я рекомендую вам внимательно прочитать, как работает ожидание: How and When to use `async` and `await`

Это не блокирующий вызов. Таким образом, вы создаете представление AboutUs. Он создает ViewModel AboutUsViewModel. Он называет

aboutUsViewModel.FirstRecord(); 

Но не ждать звонка, чтобы быть полным (dont't забудьте вы отметили вашу функцию FirstRecord как асинхронном ...)

Так называет

Model.AboutUs obj = await _db.GetAllData(); 

И непосредственно возвращайтесь к вызывающему абоненту из-за оператора ожидания. Вот почему сразу перейти к

lblContent.Text = aboutUsViewModel.AboutUsContent; 

Что вы хотели бы что-то вроде

await aboutUsViewModel.FirstRecord(); 

Ждать вызова будет завершена перед переходом к следующей строке.Но, конечно, вы не можете этого сделать, потому что вы находитесь в конструкторе, и у вас нет конструктора async. И вызов базы данных (или, фактически, ничего, что могло бы сбой) в конструкторе, в любом случае, является плохим.

Я бы посоветовал вам разрешить только InitializeComponent() в конструкторе, а затем использовать что-то вроде события OnDataLoaded() вашего представления для выполнения вашего асинхронного вызова с ожиданием.

Надеюсь, это поможет.

+0

Спасибо, что вызвали меня. Не вижу реальной проблемы. Я не могу найти метод OnDataLoaded() в xamarin.forms. Поэтому я использую метод OnAppearing(). –

+0

, но проблема в том, когда метод GetAllData вызывает его, «ошибка объекта не задана экземпляром объекта». –

+0

OnAppearing, вероятно, скоро, вам нужно искать другое событие позже или просто вызвать что-то вроде функции инициализации вручную. – Ouarzy