【问题标题】:ListView not updating on new inserted items into ObservableCollection on UWP for Windows 10ListView 未将新插入的项目更新到 UWP for Windows 10 上的 ObservableCollection
【发布时间】:2016-06-12 14:43:34
【问题描述】:

我试图了解所有这些是如何连接的,我需要一些帮助。 到目前为止,我可以在 sqlite 数据库中插入、更新、删除,但我无法让 UI 自动显示来自数据库的更改,而无需我在对数据库进行更改时更新 ListView 上的 ItemsSource。即:

在我的 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 我有一个简单的页面,有两个按钮和 Listview

<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 中进行一些更改以及如何实现?

【问题讨论】:

    标签: sqlite listview win-universal-app observablecollection inotifypropertychanged


    【解决方案1】:

    您将 ObservableCollection 转换为 List() 这就是它不更新的原因。改成:

    lvTasksList.ItemsSource = Tasks;

    当你添加一个项目时,你不必再次从 db 读取

    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);
        }
    

    【讨论】:

    • 这个解决方案非常简单,只是不知道当我要更新某些东西时这是否​​会起作用,即列表和数据库也会更新。我会尝试让你知道。谢谢
    • 我可以看到你已经实现 INotifyPropertyChanged 女巫通知项目内的值是否已更改。我可以看到您已正确实施。另外我强烈建议确保conn.Insert(Task);conn.Update(Task); 是成功的。你可以返回一个 bool e.x.布尔result =conn.Insert(Task);
    【解决方案2】:

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

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

    【讨论】:

    • 嘿伊戈尔,我明白你说的我只是找不到更新当前任务而不是将其设置为新的 ObservableCollection 的方法。我的意思是我需要对模型类进行一些更改吗?
    猜你喜欢
    • 1970-01-01
    • 2020-03-23
    • 2018-06-29
    • 1970-01-01
    • 2016-10-03
    • 2014-01-15
    • 2011-07-02
    • 2019-10-25
    相关资源
    最近更新 更多