星期二, 8月 29, 2017

[X.Form] ListView - 更新資料

根據
的筆記,重點簡單記就是,ListView 資料來源有變更時,要透過 ObservableCollection 來通知,這樣 ListView 操作時才不會拋出 Exception

Model
namespace ListViewUpdate
{
    public class Product
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

        public static List<Product> GetData()
        {
            return new List<Product>
            {
                new Product() { Name = "楓葉" } ,
                new Product() { Name = "樹" } ,
                new Product() { Name = "花" } ,
                new Product() { Name = "煙火" } ,
                new Product() { Name = "夜景" }
            };
        }
    }
}
ViewModel
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
// ObservableCollection 所在的 namespace
using System.Collections.ObjectModel;

namespace ListViewUpdate
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        // 引發錯誤版本
        public List<Product> Source { get; set; }

        public ICommand CmdInsert
        {
            get
            {
                return new Command(() => Source.Add(new Product() { Name = "植物" }));
            }
        }

        // 可更新版本
        public ObservableCollection<Product> UpdatableSource { get; set; }

        public ICommand CmdUpdatableInsert
        {
            // 上課內容是用 List.Insert 插到第一個順位
            get
            {
                return new Command(() => UpdatableSource.Add(new Product() { Name = "植物" }));
            }
        }

        public ViewModel()
        {
            // 引發錯誤版本
            Source = Product.GetData();

            // 可更新版本
            ObservableCollection<Product> ProdList = new ObservableCollection<Product>();
            foreach (var item in Product.GetData())
            {
                ProdList.Add(item);
            }

            UpdatableSource = ProdList;
        }
    }
}

Xaml-引發錯誤
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ListViewUpdate"
             x:Class="ListViewUpdate.Update">
    <ContentPage.BindingContext>
        <local:ViewModel/>
    </ContentPage.BindingContext>
    
    <ContentPage.Content>
        <StackLayout>
            <ListView ItemsSource = "{Binding Source}"/>
            <Button x:Name="btnInsert" Text="引發錯誤" Command="{Binding CmdInsert}"></Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
[X.Form] ListView - 更新資料-1

按 "引發錯誤" Button 對 Source 新增一筆資料,再去點選 ListView 就會出現下面 Exception

[X.Form] ListView - 更新資料-2

在 Yotta 課程內,老師有介紹輸出視窗內的錯誤訊息,但練習時錯誤訊息只拋出下圖訊息

[X.Form] ListView - 更新資料-3

Yotta 課程,老師 demo 輸出視窗內的錯誤訊息,練習時沒出現,只能直接紀錄囉
The contact of the adapter has changed but ListView did not receive a notification.
Xaml-可更新
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ListViewUpdate"
             x:Class="ListViewUpdate.Update">
    <ContentPage.BindingContext>
        <local:ViewModel/>
    </ContentPage.BindingContext>
    
    <ContentPage.Content>
        <StackLayout>
            <ListView ItemsSource = "{Binding UpdatableSource}"/>
            <Button x:Name="btnUpdatableInsert" Text="可更新" Command="{Binding CmdUpdatableInsert}"></Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
[X.Form] ListView - 更新資料-5

按 "可更新" Button 對 Source 新增一筆資料,ListView 上就會出現該資訊

[X.Form] ListView - 更新資料-4

沒有留言:

張貼留言