Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Esta parte do tutorial apresenta os conceitos de modos de exibição e modelos de dados.
Nos passos anteriores do tutorial, adicionaste uma nova página ao project que permite ao utilizador guardar, editar ou eliminar uma única nota. No entanto, como o aplicativo precisa lidar com mais de uma nota, você precisa adicionar outra página que exiba todas as anotações (chame-a de AllNotesPage). Esta página permite ao utilizador escolher uma nota para abrir na página do editor, para que possa vê-la, editar ou eliminá-la. Ele também deve permitir que o usuário crie uma nova nota.
Para conseguir isso, AllNotesPage precisa ter uma coleção de notas, e uma maneira de exibir a coleção. É aqui que o aplicativo tem problemas porque os dados da nota estão fortemente vinculados ao NotePage arquivo. No AllNotesPage, você deseja apenas exibir todas as anotações em uma lista ou outra exibição de coleção, com informações sobre cada nota, como a data em que foi criada e uma visualização do texto. Com o texto da nota firmemente ligado ao controlo TextBox, não há forma de fazer isto.
Antes de adicionar uma página para mostrar todas as notas, vamos fazer algumas alterações para separar os dados da nota da apresentação da nota.
Vistas e modelos
Normalmente, uma aplicação WinUI 3 tem pelo menos uma camada de visualização e uma camada de dados.
A camada de exibição define a interface do usuário usando marcação XAML. A marcação inclui expressões de vinculação de dados (como x:Bind) que definem a conexão entre componentes específicos da interface do usuário e membros de dados. Os arquivos code-behind às vezes são usados como parte da camada de exibição para conter código adicional necessário para personalizar ou manipular a interface do usuário ou para extrair dados de argumentos do manipulador de eventos antes de chamar um método que executa o trabalho nos dados.
A camada de dados, ou modelo, define os tipos que representam os dados do seu aplicativo e a lógica relacionada. Essa camada é independente da camada de exibição e você pode criar várias exibições diferentes que interagem com os dados.
Atualmente, o NotePage representa uma exibição de dados (o texto da nota). No entanto, depois de os dados serem lidos no aplicativo a partir do arquivo do sistema, eles existem apenas na Text propriedade do TextBox em NotePage. Não é representado na aplicação de uma forma que lhe permita apresentar os dados de formas diferentes ou em locais diferentes; ou seja, o aplicativo não tem uma camada de dados. Agora vais reestruturar o projeto para criar a camada de dados.
Separe a vista e o modelo
Sugestão
Pode descarregar ou ver o código deste tutorial no repositório GitHub. Para ver o código tal como está neste passo, veja este commit: note page - view-model.
Refatore o código existente para separar o modelo da visualização. As próximas etapas organizarão o código para que as exibições e os modelos sejam definidos separadamente uns dos outros.
Em Solution Explorer, clique com o botão direito no WinUINotes project e selecione Adicionar>Nova Pasta. Dê um nome à pasta Models.
Clique com o botão direito no WinUINotes project novamente e selecione Adicionar>Nova Pasta. Dê um nome à pasta Views.
Localize o NotePage.xaml item e arraste-o para a Views pasta. O NotePage.xaml.cs arquivo deve ser movido com ele.
Observação
Quando move um ficheiro, o Visual Studio normalmente avisa-o de que a operação de mudança pode demorar muito tempo. Isso não deve ser um problema aqui, pressione OK se vir este aviso.
O Visual Studio também pode perguntar se quer ajustar o namespace do ficheiro movido. Selecione Não. Você alterará o namespace nas próximas etapas.
Atualizar o namespace de exibição
Agora que a exibição foi movida para a Views pasta, você precisará atualizar os namespaces para corresponder. O namespace para os arquivos XAML e code-behind das páginas é definido como WinUINotes. Isso precisa ser atualizado para WinUINotes.Views.
No painel Solution Explorer, expanda NotePage.xaml para revelar o ficheiro de código subjacente.
Clique duas vezes no NotePage.xaml.cs item para abrir o editor de código, se ele ainda não estiver aberto. Altere o namespace para
WinUINotes.Views:namespace WinUINotes.ViewsClique duas vezes no NotePage.xaml item para abrir o editor XAML se ele ainda não estiver aberto. O namespace antigo é referenciado por meio do atributo
x:Class, que define qual tipo de classe é o code-behind para o XAML. Esta entrada não é apenas o namespace, mas o namespace com o tipo. Altere o valorx:ClassparaWinUINotes.Views.NotePage:x:Class="WinUINotes.Views.NotePage"
Corrigir a referência de namespace em MainWindow
Na etapa anterior, você criou a página de anotações e atualizou MainWindow.xaml para navegar até ela. Lembre-se de que [ele/o elemento] foi mapeado com o mapeamento do namespace local:. É prática comum mapear o nome local para o namespace raiz do seu projeto, e o modelo do Visual Studio já faz isso automaticamente (xmlns:local="using:WinUINotes"). Agora que a página foi movida para um novo namespace, o mapeamento de tipo no XAML agora é inválido.
Felizmente, você pode adicionar seus próprios mapeamentos de namespace conforme necessário. Precisas de fazer isto para aceder a itens em diferentes pastas que se criem no teu projeto. Esse novo namespace XAML será mapeado para o namespace de WinUINotes.Views, então nomeie-o views. A declaração deve ser semelhante ao seguinte atributo: xmlns:views="using:WinUINotes.Views".
No painel Solution Explorer, clique duas vezes na entrada MainWindow.xaml para a abrir no editor XAML.
Adicione este novo mapeamento de namespace na linha abaixo do mapeamento para
local:xmlns:views="using:WinUINotes.Views"O
localnamespace XAML foi usado para definir aFrame.SourcePageTypepropriedade, portanto, altere-a paraviewslá. Seu XAML agora deve ter esta aparência:<Window x:Class="WinUINotes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:WinUINotes" xmlns:views="using:WinUINotes.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="WinUI Notes"> <!-- ... Unchanged XAML not shown. --> <Frame x:Name="rootFrame" Grid.Row="1" SourcePageType="views:NotePage"/> <!-- ... Unchanged XAML not shown. --> </Window>Compile e execute a aplicação. O aplicativo deve ser executado sem erros de compilador e tudo ainda deve funcionar como antes.
Definir o modelo
Atualmente, o modelo (os dados) está incorporado na visualização de notas. Você criará uma nova classe para representar os dados de uma página de anotação:
No painel Solution Explorer, clique com o botão direito na pasta Models e selecione Add>Class... .
Nomeie a classe Note.cs e pressione Add. O Note.cs arquivo será aberto no editor de códigos.
Substitua o Note.cs código no arquivo por este código, que faz a classe
publice adiciona propriedades e métodos para manipular uma nota:using System; using System.Threading.Tasks; using Windows.Storage; namespace WinUINotes.Models { public class Note { private StorageFolder storageFolder = ApplicationData.Current.LocalFolder; public string Filename { get; set; } = string.Empty; public string Text { get; set; } = string.Empty; public DateTime Date { get; set; } = DateTime.Now; public Note() { Filename = "notes" + DateTime.Now.ToBinary().ToString() + ".txt"; } public async Task SaveAsync() { // Save the note to a file. StorageFile noteFile = (StorageFile)await storageFolder.TryGetItemAsync(Filename); if (noteFile is null) { noteFile = await storageFolder.CreateFileAsync(Filename, CreationCollisionOption.ReplaceExisting); } await FileIO.WriteTextAsync(noteFile, Text); } public async Task DeleteAsync() { // Delete the note from the file system. StorageFile noteFile = (StorageFile)await storageFolder.TryGetItemAsync(Filename); if (noteFile is not null) { await noteFile.DeleteAsync(); } } } }Salve o arquivo.
Você notará que esse código é muito semelhante ao código do , NotePage.xaml.cscom algumas alterações e adições.
Filename e Text foram alterados para public propriedades, e uma nova Date propriedade foi adicionada.
O código para salvar e excluir os arquivos foi colocado em public métodos. É basicamente idêntico ao código que você usou nos manipuladores de eventos de botão Click no NotePage, mas o código extra para atualizar a exibição depois que o arquivo é excluído foi removido. Não é necessário aqui porque você usará a vinculação de dados para manter o modelo e a exibição sincronizados.
Essas assinaturas de método assíncrono retornam Task em vez de void. A Task classe representa uma única operação assíncrona que não retorna um valor. A menos que a assinatura do método exija void, como é o caso dos manipuladores de eventos Click, os métodos async devem retornar um Task.
Você também não manterá mais uma referência ao StorageFile que contém a nota. Você apenas tenta obter o arquivo quando precisar dele para salvar ou excluir.
No NotePage, você usou um espaço reservado para o nome do arquivo: note.txt. Agora que o aplicativo suporta mais de uma nota, os nomes de arquivo para notas salvas precisam ser diferentes e exclusivos. To do isto, defina a propriedade Filename no construtor. Você pode usar o método DateTime.ToBinary para criar uma parte do nome do arquivo com base na hora atual e tornar os nomes de arquivo exclusivos. O nome do ficheiro gerado tem o seguinte aspeto: notes-8584626598945870392.txt.
Atualizar a página de notas
Agora você pode atualizar a NotePage visualização para usar o Note modelo de dados e excluir o código que foi movido para o Note modelo.
Abra o arquivo Views\NotePage.xaml.cs se ele ainda não estiver aberto no editor.
Depois da última instrução
usingna parte superior da página, adicione uma nova instruçãousingpara permitir que o seu código acesse as classes na pasta e namespaceModels.using WinUINotes.Models;Exclua estas linhas da classe:
private StorageFolder storageFolder = ApplicationData.Current.LocalFolder; private StorageFile? noteFile = null; private string fileName = "note.txt";Em vez disso, adicione um
Noteobjeto nomeadonoteModelem seu lugar. Isso representa os dados da nota queNotePagefornece uma visualização de.private Note? noteModel;Você também não precisa mais do
NotePage_Loadedmanipulador de eventos. Você não estará lendo texto diretamente do arquivo de texto para o TextBox. Em vez disso, o texto da nota será lido emNoteobjetos. Você adicionará o código para isso quando adicionar oAllNotesPageem uma etapa posterior. Exclua essas linhas.Loaded += NotePage_Loaded; ... private async void NotePage_Loaded(object sender, RoutedEventArgs e) { noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName); if (noteFile is not null) { NoteEditor.Text = await FileIO.ReadTextAsync(noteFile); } }Substitua o código no método
SaveButton_Clickpor este:if (noteModel is not null) { await noteModel.SaveAsync(); }Substitua o código no método
DeleteButton_Clickpor este:if (noteModel is not null) { await noteModel.DeleteAsync(); }
Agora você pode atualizar o arquivo XAML para usar o Note modelo. Anteriormente, você lia o texto diretamente do arquivo de texto para a TextBox.Text propriedade no arquivo code-behind. Agora, você usa a vinculação de dados para a Text propriedade.
Abra o arquivo Views\NotePage.xaml se ele ainda não estiver aberto no editor.
Adicione um
Textatributo aoTextBoxcontrole. Vincule-o à propriedadeTextdenoteModel:Text="{x:Bind noteModel.Text, Mode=TwoWay}".Atualize o
Headerpara vincular àDatepropriedade denoteModel:Header="{x:Bind noteModel.Date.ToString()}".<TextBox x:Name="NoteEditor" <!-- ↓ Add this line. ↓ --> Text="{x:Bind noteModel.Text, Mode=TwoWay}" AcceptsReturn="True" TextWrapping="Wrap" PlaceholderText="Enter your note" <!-- ↓ Update this line. ↓ --> Header="{x:Bind noteModel.Date.ToString()}" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="400" Grid.Column="1"/>
A associação de dados é uma maneira de a interface do usuário do seu aplicativo exibir dados e, opcionalmente, permanecer sincronizada com esses dados. A Mode=TwoWay configuração na associação significa que as propriedades TextBox.Text e noteModel.Text são sincronizadas automaticamente. Quando o texto é atualizado no TextBox, as alterações são refletidas na propriedade Text do noteModel, e se o noteModel.Text for alterado, as atualizações são refletidas no TextBox.
A Header propriedade usa o padrão Mode de OneTime porque a noteModel.Date propriedade não é alterada depois que o arquivo é criado. Esse código também demonstra um recurso poderoso de x:Bind, chamado ligação de função, que permite usar uma função como ToString como uma etapa no caminho de ligação.
Importante
É importante escolher o BindingMode correto; caso contrário, a vinculação de dados pode não funcionar conforme o esperado. (O erro comum com {x:Bind} é esquecer-se de alterar o valor padrão BindingMode quando OneWay ou TwoWay for necessário.)
| Nome | Description |
|---|---|
OneTime |
Atualiza a propriedade de destino somente quando a associação é criada. Padrão para {x:Bind}. |
OneWay |
Atualiza a propriedade de destino quando a associação é criada. As alterações no objeto de origem também podem se propagar para o destino. Padrão para {Binding}. |
TwoWay |
Atualiza o destino ou o objeto de origem quando ambos são alterados. Quando a associação é criada, a propriedade de destino é atualizada a partir da origem. |
A vinculação de dados oferece suporte à separação de seus dados e da interface do usuário, e isso resulta em um modelo conceitual mais simples, bem como melhor legibilidade, estabilidade e manutenção do seu aplicativo.
No WinUI, há dois tipos de vinculação que você pode escolher:
- A
{x:Bind}extensão de marcação é processada em tempo de compilação. Alguns dos seus benefícios são o desempenho melhorado e a validação em tempo de compilação das suas expressões de ligações. É recomendado para vinculação em aplicativos WinUI. - A extensão de marcação
{Binding}é processada em tempo de execução e utiliza inspeção de objetos de uso geral durante a execução.
Saiba mais nos documentos:
Vinculação de dados e MVVM
Model-View-ViewModel (MVVM) é um padrão de design arquitetónico de UI para desacoplar código UI e código não-UI, popular entre os programadores .NET. Você provavelmente verá e ouvirá isso mencionado à medida que aprender mais sobre como criar aplicativos WinUI. Separar as visualizações e os modelos, como você fez aqui, é o primeiro passo para uma implementação MVVM completa do aplicativo, mas é até onde você vai neste tutorial.
Observação
Usamos o termo "modelo" para nos referir ao modelo de dados neste tutorial, mas é importante observar que esse modelo está mais alinhado com o ViewModel em uma implementação MVVM completa, ao mesmo tempo em que incorpora aspetos do modelo.
Para saber mais sobre MVVM, consulte estes recursos:
Windows developer