0

我试图了解所有连接如何,我需要一些帮助。 到目前为止,我可以做插入,更新,删除到sqlite数据库,但我不能让UI显示从数据库的更改自动没有我更新ListView上的ItemsSource每当对数据库进行更改。即:ListView不会更新到Windows 10的UWP上的ObservableCollection中的新插入项目

在我App.xaml.cs

public App() 
     { 
      this.InitializeComponent(); 
      this.Suspending += OnSuspending; 

      //Connection to the database and create the table if not there 
      string path = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite"); 
      SQLiteConnection conn = new SQLiteConnection(path); 
      conn.CreateTable<CheckListItemModel>(); 
     } 

比我MainPage.xaml中我有两个按钮,一个简单的页面和列表视图

<Page 
    x:Class="Personal_Checklist_2.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:Personal_Checklist_2" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="100" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <StackPanel Grid.Row="0" Orientation="Horizontal" > 
      <Button Content="Add Sample To Db" Click="Add_Sample_To_Db_Click" Margin="10,0,10,0" /> 
      <Button Content="Clear Tasks" Click="Clear_Tasks_Click" /> 
     </StackPanel> 

     <ListView Name="lvListView" Grid.Row="1" > 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="{Binding Title}" /> 
         <TextBlock Text="{Binding Id}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </Grid> 
</Page> 

MainPage.xaml.cs代码隐藏我也保持简单,因为我知道只是添加新行到表中并清除表

using Personal_Checklist_2.DataModels; 
using System.IO; 
using System.Linq; 
using SQLite; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using System.Collections.ObjectModel; 

namespace Personal_Checklist_2 
{ 
    public sealed partial class MainPage : Page 
    { 
     static string path = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite"); 
     ObservableCollection<CheckListItemModel> Tasks = new ObservableCollection<CheckListItemModel>(); 

     public MainPage() 
     { 
      this.InitializeComponent(); 
      using (var conn = new SQLiteConnection(path)) 
      { 
       var query = conn.Table<CheckListItemModel>(); 
       Tasks = new ObservableCollection<CheckListItemModel>(query.ToList()); 

       lvTasksList.ItemsSource = Tasks.ToList(); //<<<--- If I dont do this, list is not updated 
      } 
     } 

     private void Add_Sample_To_Db_Click(object sender, RoutedEventArgs e) 
     { 
      var Task = new CheckListItemModel() 
      { 
       taskTitle = "Sample Task" 
      }; 

      using (var conn = new SQLiteConnection(path)) 
      { 
       conn.Insert(Task); 
       var query = conn.Table<CheckListItemModel>(); 
       Tasks = new ObservableCollection<CheckListItemModel>(query.ToList()); 
       lvTasksList.ItemsSource = Tasks.ToList(); //<<<--- If I dont do this, list is not updated 
      } 
     } 

     private void Clear_Tasks_Click(object sender, RoutedEventArgs e) 
     { 
      using (var conn = new SQLiteConnection(path)) 
      { 
       conn.DeleteAll<CheckListItemModel>(); 
       var query = conn.Table<CheckListItemModel>(); 
       Tasks = new ObservableCollection<CheckListItemModel>(query.ToList()); 
       lvTasksList.ItemsSource = Tasks.ToList(); //<<<--- If I dont do this, list is not updated 
      } 
     } 
    } 
} 

数据库表的模型看起来像这样CheckListItemModel.cs

using SQLite; 
using System; 
using System.ComponentModel; 

namespace Personal_Checklist_2.DataModels 
{ 
    class CheckListItemModel : INotifyPropertyChanged 
    { 
     #region Private fields on DataModel 
     private string _taskTitle; 
     #endregion 

     #region Public properties on DataModel 
     [PrimaryKey, AutoIncrement] 
     public int taskId { get; set; } 

     public string taskTitle 
     { 
      get { return _taskTitle; } 
      set { _taskTitle = value; NotifyPropertyChanged("taskTitle"); } 
     } 
     #endregion 

     #region INotifyPropertyChanged implementation 
     public event PropertyChangedEventHandler PropertyChanged; 
     private void NotifyPropertyChanged(String propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (null != handler) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     #endregion 
    } 
} 

不过,这并不正确看我这个样子。有没有办法实现这一点,而无需设置listview.ItemsSource每次在db.sqlite中的一些变化,以及如何?

回答

2

你投了你的ObservableCollection toList()这就是为什么它不更新。将其更改为:

lvTasksList.ItemsSource = Tasks;

而当你添加一个项目你不必再次读取数据库

private void Add_Sample_To_Db_Click(object sender, RoutedEventArgs e) 
    { 
     var Task = new CheckListItemModel() 
     { 
      taskTitle = "Sample Task" 
     }; 

     using (var conn = new SQLiteConnection(path)) 
     { 
      conn.Insert(Task); 
     } 
     Tasks.Add(Task); 
    } 
+0

这个解决方案非常简单,只是不知道这是否会工作,当我要更新的东西,即列表和数据库将得到更新。我会试着让你知道。谢谢 – al1en

+0

正如我看到你已经实现INotifyPropertyChanged witch通知如果一个项目内的值已经改变。我可以看到你已经正确实施它。另外,我强烈建议确保'conn.Insert(Task);'或'conn.Update(Task);'是成功的。你可以返回一个bool e.x. bool'result = conn.Insert(Task);' – Stamos

0

您每次都创建一个新的ObservableCollection,而不是绑定到单个ObservableCollection并更改其中的项目。

因此,请保留Tasks作为单个ObservableCollection并根据数据库查询结果更新其内容。

+0

嘿伊戈尔,我给你说什么,我只是不能找到一种方法如何更新当前的任务而不是将其设置为新的ObservableCollection <>。我的意思是我需要在模型课上做一些改变吗? – al1en

相关问题