共用方式為


新增所有附注的檢視和模型

本教學課程的這個部分會將新頁面新增至應用程式,此檢視會顯示先前建立的所有筆記。

多個附註和流覽

目前記 事檢視會顯示單一附註 。 若要顯示所有已儲存的筆記,請建立新的檢視和模型: AllNotes

  1. [方案總管] 窗格中,以滑鼠右鍵按單擊Views資料夾,然後選取 [新增>專案...
  2. 在 [ 新增專案 ] 對話框中,選取視窗左側範本清單中的 WinUI 。 接下來,選取 空白頁面 (WinUI 3) 範本。 為檔案AllNotesPage.xaml命名,然後按 [新增]。
  3. [方案總管] 窗格中,以滑鼠右鍵按下Models資料夾,然後選取 [新增>類別...
  4. 為類別AllNotes.cs命名,然後按 [新增]。

小提示

您可以從 GitHub 存放庫下載或檢視本教學課程的程式代碼。 若要查看此步驟中的程序代碼,請參閱此認可: 所有附注檢視和模型

撰寫 AllNotes 模型的程式代碼

新的數據模型代表顯示多個筆記所需的數據。 在這裡,您將從應用程式的本機記憶體取得所有附註,並建立您將在 中顯示的Note物件集合AllNotesPage

  1. [方案總管 ] 窗格中,開啟 Models\AllNotes.cs 檔案。

  2. 將檔案中的 AllNotes.cs 程式碼取代為以下程式碼:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using Windows.Storage;
    
    namespace WinUINotes.Models
    {
        public class AllNotes
        {
            public ObservableCollection<Note> Notes { get; set; } = 
                                        new ObservableCollection<Note>();
    
            public AllNotes()
            {
                LoadNotes();
            }
    
            public async void LoadNotes()
            {
                Notes.Clear();
                // Get the folder where the notes are stored.
                StorageFolder storageFolder = 
                              ApplicationData.Current.LocalFolder;
                await GetFilesInFolderAsync(storageFolder);
            }
    
            private async Task GetFilesInFolderAsync(StorageFolder folder)
            {
                // Each StorageItem can be either a folder or a file.
                IReadOnlyList<IStorageItem> storageItems = 
                                            await folder.GetItemsAsync();
                foreach (IStorageItem item in storageItems)
                {
                    if (item.IsOfType(StorageItemTypes.Folder))
                    {
                        // Recursively get items from subfolders.
                        await GetFilesInFolderAsync((StorageFolder)item);
                    }
                    else if (item.IsOfType(StorageItemTypes.File))
                    {
                        StorageFile file = (StorageFile)item ;
                        Note note = new Note()
                        {
                            Filename = file.Name,
                            Text = await FileIO.ReadTextAsync(file),
                            Date = file.DateCreated.DateTime
                        };
                        Notes.Add(note);
                    }
                }
            }
        }
    }
    

上述程式代碼會宣告名為 Note的專案集合Notes,並使用 LoadNotes 方法從應用程式的本機記憶體載入筆記。

集合 Notes 會使用 ObservableCollection,這是一個特別的集合,適用於數據系結。 當列出多個專案,例如 ItemsView 的控件系結至 ObservableCollection時,兩者會一起運作,以自動讓專案清單與集合保持同步。 如果專案加入至集合,控件就會自動更新為新的專案。 如果專案新增至清單,則會更新集合。

在檔中深入瞭解:

AllNotes既然模型已準備好提供檢視的數據,您必須在 中AllNotesPage建立模型的實例,讓檢視可以存取模型。

  1. [方案總管 ] 窗格中,開啟 Views\AllNotesPage.xaml.cs 檔案。

  2. 在類別中AllNotesPage,新增此程式代碼以建立名為 AllNotes模型:

    public sealed partial class AllNotesPage : Page
    {
        // ↓ Add this. ↓
        private AllNotes notesModel = new AllNotes();
        // ↑ Add this. ↑
    
        public AllNotesPage()
        {
            this.InitializeComponent();
        }
    }
    

設計 AllNotes 頁面

接下來,您必須設計檢視以支援 AllNotes 模型。

  1. [方案總管 ] 窗格中,開啟 Views\AllNotesPage.xaml 檔案。

  2. <Grid> ... </Grid> 元素取代為下列標記:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <CommandBar DefaultLabelPosition="Right">
            <AppBarButton Icon="Add" Label="New note"/>
            <CommandBar.Content>
                <TextBlock Text="Quick notes" Margin="16,8" 
                       Style="{ThemeResource SubtitleTextBlockStyle}"/>
            </CommandBar.Content>
        </CommandBar>
    
        <ItemsView ItemsSource="{x:Bind notesModel.Notes}" 
               Grid.Row="1" Padding="16" >
            <ItemsView.Layout>
                <UniformGridLayout MinItemWidth="200"
                               MinColumnSpacing="12"
                               MinRowSpacing="12"
                               ItemsJustification="Start"/>
            </ItemsView.Layout>
        </ItemsView>
    </Grid>
    

先前的 XAML 引進了一些新概念:

  • CommandBar 控件包含 AppBarButton。 此按鈕具有 LabelIcon,且會受到 CommandBar 包含它的 影響。 例如,這會 CommandBar 將其按鈕的標籤位置設定為 Right。 命令行通常會顯示在應用程式頂端,以及頁面標題。
  • ItemsView 控件會顯示專案的集合,在此案例中,會系結至模型的 Notes 屬性。 項目檢視會透過 ItemsView.Layout 屬性設定項目呈現的方式。 在這裡,您會使用 UniformGridLayout

現在您已建立 AllNotesPage,您必須上次更新 MainWindow.xaml 一次,使其載入 AllNotesPage 而不是個別 NotePage

  1. 在 [ 方案總管] 窗格中,開啟 MainWindow.xaml 檔案。

  2. 更新 專案 rootFrame ,讓 SourcePageType 指向 views.AllNotesPage,如下所示:

    <Frame x:Name="rootFrame" Grid.Row="1"
           SourcePageType="views:AllNotesPage"/>
    

如果您現在執行應用程式,您會看到您先前建立的附註已 ItemsView 載入控件。 不過,它只會顯示為物件的字串表示。 ItemsView不知道應該如何顯示此專案。 您將在下一節修正此問題。

具有附注清單的附註應用程式 UI,其中顯示 Note 類別名稱,而不是附註內容。

新增數據範本

您必須指定 DataTemplate ,以告知 ItemsView 應該如何顯示資料項。 DataTemplate會指派給的 ItemsView 屬性。 針對集合中的每個專案,會產生 ItemsView.ItemTemplate 宣告的 XAML。

  1. [方案總管 ] 窗格中,按兩下專案 AllNotesPage.xaml ,以在 XAML 編輯器中開啟它。

  2. 在 對應下方的這一行中新增這個新的命名空間對應 local

    xmlns:models="using:WinUINotes.Models"
    
  3. <Page.Resources>在開頭<Page...>標記之後新增專案。 這會從Page 屬性取得 ResourceDictionary,讓您可以將 XAML 資源加入其中。

    <Page
        x:Class="WinUINotes.Views.AllNotesPage"
        ... >
    <!-- ↓ Add this. ↓ -->
    <Page.Resources>
    
    </Page.Resources>
    
  4. 在 元素內 <Page.Resources> ,新增 DataTemplate 描述如何顯示 Note 項目的 。

    <Page.Resources>
        <!-- ↓ Add this. ↓ -->
        <DataTemplate x:Key="NoteItemTemplate" 
                      x:DataType="models:Note">
            <ItemContainer>
                <Grid Background="LightGray">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="120"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{x:Bind Text}" Margin="12,8"
                               TextWrapping="Wrap"
                               TextTrimming="WordEllipsis"/>
                    <Border Grid.Row="1" Padding="8,6,0,6"
                            Background="Gray">
                        <TextBlock Text="{x:Bind Date}"
                                   Foreground="White"/>
                    </Border>
                </Grid>
            </ItemContainer>
        </DataTemplate>
        <!-- ↑ Add this. ↑ -->
    </Page.Resources>
    
  5. 在 XAML ItemsView中,將 ItemTemplate 屬性指派給您剛才建立的數據範本:

    <ItemsView ItemsSource="{x:Bind notesModel.Notes}"
               Grid.Row="1" Margin="24"
               <!-- ↓ Add this. ↓ -->
               ItemTemplate="{StaticResource NoteItemTemplate}">
    
  6. 建置並執行應用程式。

當您在 中使用 x:BindDataTemplate標記延伸時,您必須在 x:DataType上指定 DataTemplate 。 在此情況下,這是個別 Note 的 (因此您必須新增 的 ModelsXAML 命名空間參考 )。 附註的範本會使用兩 TextBlock 個控件,這些控件系結至附註的 TextDate 屬性。 Grid 元素用於配置,並提供背景色彩。 Border 元素用於日期的背景。 (XAML Border 元素可以同時提供大綱和背景。

當您執行應用程式時,數據範本會套用至您的 Note 專案,如果您的 Windows 個人化 > 色彩設定使用淺色模式,則看起來像這樣:

附注應用程式 UI 與附註清單,其中顯示資料範本所格式化的附註內容和日期。

不過,如果您的 Windows 個人化 > 色彩設定使用深色模式,看起來會像這樣:

具有深色背景但淺灰色附註範本的附註應用程式 UI。

這不是應用程式的預期外觀。 之所以發生,是因為附註的數據範本中有硬式編碼的色彩值。 根據預設,WinUI 元素會適應使用者的深色或淺色喜好設定。 當您定義自己的元素,例如數據範本時,必須小心執行相同的動作。

當您在 XAML ResourceDictionary中定義資源時,您必須指派 x:Key 值來識別資源。 然後,您可以使用該 x:Key 屬性,透過 {StaticResource} 標記延伸或 {ThemeResource} 標記延伸,在 XAML 中擷取資源。

  • 不論色彩主題為何,都{StaticResource}相同,因此會用於 或 Font 設定等Style專案。
  • {ThemeResource}會根據選取的色彩主題進行變更,因此會用於ForegroundBackground和其他色彩相關屬性。

WinUI 包含各種不同的內建資源,可讓您用來讓您的應用程式遵循 Fluent 樣式指導方針,以及輔助功能指導方針。 您將使用內建的主題資源取代數據範本中的硬式編碼色彩,並套用一些其他資源以符合 Fluent Design 指導方針。

  1. 在您先前新增的數據範本中,更新此處指示的區段以使用內建資源:

    <DataTemplate x:Key="NoteItemTemplate" 
                  x:DataType="models:Note">
    
    <!-- ↓ Update this. ↓ -->
        <ItemContainer CornerRadius="{StaticResource OverlayCornerRadius}">
            <Grid Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
                  BorderThickness="1" 
                  BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
                  CornerRadius="{StaticResource OverlayCornerRadius}">
    <!-- ↑ Update this. ↑ -->
    
                <Grid.RowDefinitions>
                    <RowDefinition Height="120"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock Text="{x:Bind Text}" Margin="12,8"
                           TextWrapping="Wrap"
                           TextTrimming="WordEllipsis"/>
    
    <!-- ↓ Update this. ↓ -->
                <Border Grid.Row="1" Padding="8,6,0,6"
                        Background="{ThemeResource SubtleFillColorSecondaryBrush}">
                    <TextBlock Text="{x:Bind Date}"
                        Style="{StaticResource CaptionTextBlockStyle}"
                        Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
    <!-- ↑ Update this. ↑ -->
    
                </Border>
            </Grid>
        </ItemContainer>
    </DataTemplate>
    

現在當您使用淺色設定執行應用程式時,看起來會像這樣:

具有淺色背景和淺色筆記範本的附註應用程式 UI。

當您以深色設定執行應用程式時,看起來會像這樣:

具有深色背景和深色筆記範本的附註應用程式 UI。

在檔中深入瞭解:

小提示

該應用程序 WinUI 3 Gallery 是了解不同 WinUI 控件和設計指南的好方法。 若要查看資料範本中使用的主題資源, 請開啟 WinUI 3 Gallery 應用程式以取得色彩指引。 您可以從該處查看資源的外觀,並直接從應用程式複製所需的值。

您也可以開啟 [印刷樣式] 頁面[幾何] 頁面 ,以查看此數據範本中使用的其他內建資源。

該應用程序 WinUI 3 Gallery 包括大多數 WinUI 3 控件、特性和功能的交互式示例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼