首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 開發實戰(53):四大資料綁定進階技巧全解析

     編輯:關於.NET

前言

資料綁定是 XAML 應用開發的核心。Windows 8 Store Apps 提供多種進階綁定方式,滿足不同場景需求。本文詳細解析 ObservableCollection、CollectionViewSource、VirtualizedFilesVector、VirtualizedItemsVector 四種綁定模式的實作要點與適用場景。

一、ObservableCollection<T>:動態集合雙向綁定

ObservableCollection<T> 實作 INotifyCollectionChanged,當集合發生增、刪、改、移動時自動通知 UI 更新,是最常用的動態資料源。

XAML 介面

<Page x:Class="XamlDemo.Binding.BindingObservableCollection" ...>
    <Grid Background="Transparent">
        <Grid Margin="120 0 0 10">
            <Grid.Resources>
                <DataTemplate x:Key="MyDataTemplate">
                    <Border Background="Blue" Width="200" CornerRadius="3" HorizontalAlignment="Left">
                        <TextBlock Text="{Binding Name}" FontSize="14.667" />
                    </Border>
                </DataTemplate>
            </Grid.Resources>
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                <Button Name="btnDelete" Content="刪除一筆記錄" Click="btnDelete_Click_1" />
                <Button Name="btnUpdate" Content="更新一筆記錄" Click="btnUpdate_Click_1" Margin="10 0 0 0" />
            </StackPanel>
            <ListView x:Name="listView" ItemTemplate="{StaticResource MyDataTemplate}" Margin="0 50 0 0" />
        </Grid>
    </Grid>
</Page>

後端程式碼

using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using XamlDemo.Model;

namespace XamlDemo.Binding
{
    public sealed partial class BindingObservableCollection : Page
    {
        private ObservableCollection<Employee> _employees;

        public BindingObservableCollection()
        {
            this.InitializeComponent();
            this.Loaded += BindingObservableCollection_Loaded;
        }

        void BindingObservableCollection_Loaded(object sender, RoutedEventArgs e)
        {
            _employees = new ObservableCollection<Employee>(TestData.GetEmployees());
            _employees.CollectionChanged += _employees_CollectionChanged;
            listView.ItemsSource = _employees;
        }

        void _employees_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            // e.Action: Add, Remove, Replace, Move, Reset
            // e.OldItems, e.NewItems, e.OldStartingIndex, e.NewStartingIndex
        }

        private void btnDelete_Click_1(object sender, RoutedEventArgs e)
        {
            _employees.RemoveAt(0); // 觸發 CollectionChanged
        }

        private void btnUpdate_Click_1(object sender, RoutedEventArgs e)
        {
            Random random = new Random();
            // 透過 INotifyPropertyChanged 通知屬性變更
            _employees.First().Name = random.Next(1000, 10000).ToString();
            // 透過集合替換觸發通知
            _employees[1] = new Employee() { Name = random.Next(1000, 10000).ToString() };
        }
    }
}

二、CollectionViewSource:資料分組顯示

CollectionViewSource 提供分組、排序、篩選功能,配合 ListView.GroupStyle 可實現分組標題與明細的階層式呈現。

XAML 介面

<Page x:Class="XamlDemo.Binding.BindingCollectionViewSource" ...>
    <Grid Background="Transparent">
        <Grid Margin="120 0 0 10">
            <ListView x:Name="listView">
                <ListView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Title}" FontSize="24.667" />
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </ListView.GroupStyle>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Title}" FontSize="14.667" Padding="50 0 0 0" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Grid>
</Page>

後端程式碼:載入 XML 並建構分組資料

using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

namespace XamlDemo.Binding
{
    public sealed partial class BindingCollectionViewSource : Page
    {
        public BindingCollectionViewSource()
        {
            this.InitializeComponent();
            this.Loaded += BindingCollectionViewSource_Loaded;
        }

        void BindingCollectionViewSource_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            XElement root = XElement.Load("SiteMap.xml");
            var items = LoadData(root);

            CollectionViewSource groupData = new CollectionViewSource();
            groupData.IsSourceGrouped = true;
            groupData.Source = items;
            groupData.ItemsPath = new PropertyPath("Items");

            listView.ItemsSource = groupData.View; // 綁定 ICollectionView
        }

        private List<GroupModel> LoadData(XElement root)
        {
            if (root == null) return null;
            var items = from n in root.Elements("node")
                        select new GroupModel
                        {
                            Title = (string)n.Attribute("title"),
                            Items = LoadData(n)
                        };
            return items.ToList();
        }

        class GroupModel
        {
            public string Title { get; set; }
            public List<GroupModel> Items { get; set; }
        }
    }
}

三、VirtualizedFilesVector:虛擬化檔案集合綁定

適用於大量檔案(如圖片庫)的高效能顯示。FileInformationFactory 產生的 VirtualizedFilesVector 僅在需要時載入縮圖與中繼資料,避免一次性讀取所有檔案導致記憶體暴增。

XAML 介面:GridView 顯示縮圖

<Page x:Class="XamlDemo.Binding.BindingVirtualizedFilesVector" ...>
    <Grid Background="Transparent">
        <Grid.Resources>
            <converter:ThumbnailConverter x:Key="ThumbnailConverter"/>
            <CollectionViewSource x:Name="itemsViewSource"/>
        </Grid.Resources>
        <GridView Name="gridView" Padding="120 0 0 10"
                  ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
                  SelectionMode="None">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid Width="160" Height="120">
                        <Border Background="Red" Width="160" Height="120">
                            <Image Source="{Binding Path=Thumbnail, Converter={StaticResource ThumbnailConverter}}"
                                   Stretch="None" Width="160" Height="120" />
                        </Border>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
</Page>

後端程式碼:查詢圖片庫並建立虛擬化向量

using Windows.Storage;
using Windows.Storage.BulkAccess;
using Windows.Storage.FileProperties;
using Windows.Storage.Search;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace XamlDemo.Binding
{
    public sealed partial class BindingVirtualizedFilesVector : Page
    {
        public BindingVirtualizedFilesVector() { this.InitializeComponent(); }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            QueryOptions queryOptions = new QueryOptions();
            queryOptions.FolderDepth = FolderDepth.Deep;
            queryOptions.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
            queryOptions.SortOrder.Clear();
            queryOptions.SortOrder.Add(new SortEntry { PropertyName = "System.FileName", AscendingOrder = true });

            StorageFileQueryResult fileQuery = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);
            var fileInformationFactory = new FileInformationFactory(fileQuery, ThumbnailMode.PicturesView, 160, ThumbnailOptions.UseCurrentScale, true);
            itemsViewSource.Source = fileInformationFactory.GetVirtualizedFilesVector();
        }
    }
}

四、VirtualizedItemsVector:檔案與資料夾混合顯示

VirtualizedItemsVector 同時包含檔案與資料夾,搭配 DataTemplateSelector 在執行期依項目類型動態選擇模板。

XAML 介面:定義兩種模板與 Selector

<Page x:Class="XamlDemo.Binding.BindingVirtualizedItemsVector" ...>
    <Grid.Resources>
        <converter:ThumbnailConverter x:Key="ThumbnailConverter"/>
        <CollectionViewSource x:Name="itemsViewSource"/>
        <DataTemplate x:Key="FolderTemplate"> ... </DataTemplate>
        <DataTemplate x:Key="FileTemplate"> ... </DataTemplate>
        <local:FileFolderInformationTemplateSelector x:Key="FileFolderInformationTemplateSelector"
            FileInformationTemplate="{StaticResource FileTemplate}"
            FolderInformationTemplate="{StaticResource FolderTemplate}" />
    </Grid.Resources>
    <GridView Name="gridView" Padding="120 0 0 10"
              ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
              ItemTemplateSelector="{StaticResource FileFolderInformationTemplateSelector}"
              SelectionMode="None" />
</Page>

後端程式碼與 TemplateSelector 實作

using Windows.Storage;
using Windows.Storage.BulkAccess;
using Windows.Storage.FileProperties;
using Windows.Storage.Search;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace XamlDemo.Binding
{
    public sealed partial class BindingVirtualizedItemsVector : Page
    {
        public BindingVirtualizedItemsVector() { this.InitializeComponent(); }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            QueryOptions queryOptions = new QueryOptions();
            queryOptions.FolderDepth = FolderDepth.Shallow;
            queryOptions.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
            queryOptions.SortOrder.Add(new SortEntry { PropertyName = "System.IsFolder", AscendingOrder = false });
            queryOptions.SortOrder.Add(new SortEntry { PropertyName = "System.ItemName", AscendingOrder = true });

            StorageItemQueryResult itemQuery = KnownFolders.PicturesLibrary.CreateItemQueryWithOptions(queryOptions);
            var fileInformationFactory = new FileInformationFactory(itemQuery, ThumbnailMode.PicturesView, 160, ThumbnailOptions.UseCurrentScale, true);
            itemsViewSource.Source = fileInformationFactory.GetVirtualizedItemsVector();
        }
    }

    public class FileFolderInformationTemplateSelector : DataTemplateSelector
    {
        public DataTemplate FileInformationTemplate { get; set; }
        public DataTemplate FolderInformationTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            return (item as FolderInformation) != null ? FolderInformationTemplate : FileInformationTemplate;
        }
    }
}

總結與選型建議

綁定類型適用場景關鍵優勢
ObservableCollection<T>一般動態列表,需即時反映增刪改簡單易用,自動通知 UI
CollectionViewSource需分組、排序、篩選的階層式資料支援 ICollectionView,聲明式分組
VirtualizedFilesVector大量檔案(圖片、影片)縮圖瀏覽虛擬化載入,記憶體效率極高
VirtualizedItemsVector檔案與資料夾混合顯示,需不同模板支援 TemplateSelector,運行期動態切換

原始碼下載:https://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved