app converted to mvvm
This commit is contained in:
parent
3b291e4fba
commit
60ec37b2c7
@ -1,12 +1,79 @@
|
|||||||
using System;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Collections.Generic;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using System.Linq;
|
using System.Windows.Input;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MauiApp2.ViewModels
|
namespace MauiApp2.ViewModels
|
||||||
{
|
{
|
||||||
class NoteViewModel
|
internal class NoteViewModel : ObservableObject, IQueryAttributable
|
||||||
{
|
{
|
||||||
|
private Models.Note _note;
|
||||||
|
|
||||||
|
public NoteViewModel()
|
||||||
|
{
|
||||||
|
_note = new Models.Note();
|
||||||
|
SaveCommand = new AsyncRelayCommand(Save);
|
||||||
|
DeleteCommand = new AsyncRelayCommand(Delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoteViewModel(Models.Note note)
|
||||||
|
{
|
||||||
|
_note = note;
|
||||||
|
SaveCommand = new AsyncRelayCommand(Save);
|
||||||
|
DeleteCommand = new AsyncRelayCommand(Delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => _note.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_note.Text != value)
|
||||||
|
{
|
||||||
|
_note.Text = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime Date => _note.Date;
|
||||||
|
|
||||||
|
public string Identifier => _note.Filename;
|
||||||
|
|
||||||
|
public ICommand SaveCommand { get; private set; }
|
||||||
|
public ICommand DeleteCommand { get; private set; }
|
||||||
|
|
||||||
|
private async Task Save()
|
||||||
|
{
|
||||||
|
_note.Date = DateTime.Now;
|
||||||
|
_note.Save();
|
||||||
|
await Shell.Current.GoToAsync($"..?saved={_note.Filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Delete()
|
||||||
|
{
|
||||||
|
_note.Delete();
|
||||||
|
await Shell.Current.GoToAsync($"..?deleted={_note.Filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query)
|
||||||
|
{
|
||||||
|
if (query.ContainsKey("load"))
|
||||||
|
{
|
||||||
|
_note = Models.Note.Load(query["load"].ToString());
|
||||||
|
RefreshProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reload()
|
||||||
|
{
|
||||||
|
_note = Models.Note.Load(_note.Filename);
|
||||||
|
RefreshProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshProperties()
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(Text));
|
||||||
|
OnPropertyChanged(nameof(Date));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,56 @@
|
|||||||
using System;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using System.Collections.Generic;
|
using MauiApp2.Models;
|
||||||
using System.Linq;
|
using System.Collections.ObjectModel;
|
||||||
using System.Text;
|
using System.Windows.Input;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MauiApp2.ViewModels
|
namespace MauiApp2.ViewModels
|
||||||
{
|
{
|
||||||
class NotesViewModel
|
internal class NotesViewModel : IQueryAttributable
|
||||||
{
|
{
|
||||||
|
public ObservableCollection<ViewModels.NoteViewModel> AllNotes { get; }
|
||||||
|
public ICommand NewCommand { get; }
|
||||||
|
public ICommand SelectNoteCommand { get; }
|
||||||
|
public NotesViewModel()
|
||||||
|
{
|
||||||
|
AllNotes = new ObservableCollection<ViewModels.NoteViewModel>(Models.Note.LoadAll().Select(n => new NoteViewModel(n)));
|
||||||
|
NewCommand = new AsyncRelayCommand(NewNoteAsync);
|
||||||
|
SelectNoteCommand = new AsyncRelayCommand<ViewModels.NoteViewModel>(SelectNoteAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task NewNoteAsync()
|
||||||
|
{
|
||||||
|
await Shell.Current.GoToAsync(nameof(Views.NotePage));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SelectNoteAsync(NoteViewModel note)
|
||||||
|
{
|
||||||
|
if (note != null)
|
||||||
|
await Shell.Current.GoToAsync($"{nameof(Views.NotePage)}?load={note.Identifier}");
|
||||||
|
}
|
||||||
|
void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query)
|
||||||
|
{
|
||||||
|
if (query.ContainsKey("deleted"))
|
||||||
|
{
|
||||||
|
string noteId = query["deleted"].ToString();
|
||||||
|
NoteViewModel matchedNote = AllNotes.Where((n) => n.Identifier == noteId).FirstOrDefault();
|
||||||
|
|
||||||
|
// If note exists, delete it
|
||||||
|
if (matchedNote != null)
|
||||||
|
AllNotes.Remove(matchedNote);
|
||||||
|
}
|
||||||
|
else if (query.ContainsKey("saved"))
|
||||||
|
{
|
||||||
|
string noteId = query["saved"].ToString();
|
||||||
|
NoteViewModel matchedNote = AllNotes.Where((n) => n.Identifier == noteId).FirstOrDefault();
|
||||||
|
|
||||||
|
// If note is found, update it
|
||||||
|
if (matchedNote != null)
|
||||||
|
matchedNote.Reload();
|
||||||
|
|
||||||
|
// If note isn't found, it's new; add it.
|
||||||
|
else
|
||||||
|
AllNotes.Add(new NoteViewModel(Note.Load(noteId)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,4 @@ public partial class AboutPage : ContentPage
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
private async void LearnMore_Clicked(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (BindingContext is Models.About about)
|
|
||||||
{
|
|
||||||
// Navigate to the specified URL in the system browser.
|
|
||||||
await Launcher.Default.OpenAsync(about.MoreInfoUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -2,19 +2,24 @@
|
|||||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="MauiApp2.Views.AllNotesPage"
|
x:Class="MauiApp2.Views.AllNotesPage"
|
||||||
|
xmlns:viewModels="clr-namespace:MauiApp2.ViewModels"
|
||||||
Title="Your Notes">
|
Title="Your Notes">
|
||||||
|
<ContentPage.BindingContext>
|
||||||
|
<viewModels:NotesViewModel />
|
||||||
|
</ContentPage.BindingContext>
|
||||||
|
|
||||||
<!-- Add an item to the toolbar -->
|
<!-- Add an item to the toolbar -->
|
||||||
<ContentPage.ToolbarItems>
|
<ContentPage.ToolbarItems>
|
||||||
<ToolbarItem Text="Add" Clicked="Add_Clicked" IconImageSource="{FontImage Glyph='+', Color=Black, Size=22}" />
|
<ToolbarItem Text="Add" Command="{Binding NewCommand}" IconImageSource="{FontImage Glyph='+', Color=Black, Size=22}" />
|
||||||
</ContentPage.ToolbarItems>
|
</ContentPage.ToolbarItems>
|
||||||
|
|
||||||
<!-- Display notes in a list -->
|
<!-- Display notes in a list -->
|
||||||
<CollectionView x:Name="notesCollection"
|
<CollectionView x:Name="notesCollection"
|
||||||
ItemsSource="{Binding Notes}"
|
ItemsSource="{Binding AllNotes}"
|
||||||
Margin="20"
|
Margin="20"
|
||||||
SelectionMode="Single"
|
SelectionMode="Single"
|
||||||
SelectionChanged="notesCollection_SelectionChanged">
|
SelectionChangedCommand="{Binding SelectNoteCommand}"
|
||||||
|
SelectionChangedCommandParameter="{Binding Source={RelativeSource Self}, Path=SelectedItem}">
|
||||||
|
|
||||||
<!-- Designate how the collection of items are laid out -->
|
<!-- Designate how the collection of items are laid out -->
|
||||||
<CollectionView.ItemsLayout>
|
<CollectionView.ItemsLayout>
|
||||||
|
|||||||
@ -1,38 +1,9 @@
|
|||||||
using MauiApp2.Models;
|
|
||||||
|
|
||||||
namespace MauiApp2.Views;
|
namespace MauiApp2.Views;
|
||||||
|
|
||||||
public partial class AllNotesPage : ContentPage
|
public partial class AllNotesPage : ContentPage
|
||||||
{
|
{
|
||||||
public AllNotesPage()
|
public AllNotesPage()
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
BindingContext = new AllNotes();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnAppearing()
|
|
||||||
{
|
{
|
||||||
((AllNotes)BindingContext).LoadNotes();
|
InitializeComponent();
|
||||||
}
|
|
||||||
|
|
||||||
private async void Add_Clicked(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
await Shell.Current.GoToAsync(nameof(NotePage));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void notesCollection_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.CurrentSelection.Count != 0)
|
|
||||||
{
|
|
||||||
// Get the note model
|
|
||||||
var note = (Note)e.CurrentSelection[0];
|
|
||||||
|
|
||||||
// Should navigate to "NotePage?ItemId=path\on\device\XYZ.notes.txt"
|
|
||||||
await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.Filename}");
|
|
||||||
|
|
||||||
// Unselect the UI
|
|
||||||
notesCollection.SelectedItem = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,11 @@
|
|||||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="MauiApp2.Views.NotePage"
|
x:Class="MauiApp2.Views.NotePage"
|
||||||
|
xmlns:viewModels="clr-namespace:MauiApp2.ViewModels"
|
||||||
Title="NotePage">
|
Title="NotePage">
|
||||||
|
<ContentPage.BindingContext>
|
||||||
|
<viewModels:NoteViewModel />
|
||||||
|
</ContentPage.BindingContext>
|
||||||
<VerticalStackLayout Spacing="10" Margin="5">
|
<VerticalStackLayout Spacing="10" Margin="5">
|
||||||
<Editor x:Name="TextEditor"
|
<Editor x:Name="TextEditor"
|
||||||
Text="{Binding Text}"
|
Text="{Binding Text}"
|
||||||
@ -11,11 +15,13 @@
|
|||||||
|
|
||||||
<Grid ColumnDefinitions="*,*" ColumnSpacing="4">
|
<Grid ColumnDefinitions="*,*" ColumnSpacing="4">
|
||||||
<Button Text="Save"
|
<Button Text="Save"
|
||||||
Clicked="SaveButton_Clicked" />
|
Command="{Binding SaveCommand}"/>
|
||||||
|
|
||||||
|
|
||||||
<Button Grid.Column="1"
|
<Button Grid.Column="1"
|
||||||
Text="Delete"
|
Text="Delete"
|
||||||
Clicked="DeleteButton_Clicked" />
|
Command="{Binding DeleteCommand}"/>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</VerticalStackLayout>
|
</VerticalStackLayout>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|||||||
@ -1,55 +1,9 @@
|
|||||||
using MauiApp2.Models;
|
|
||||||
|
|
||||||
namespace MauiApp2.Views;
|
namespace MauiApp2.Views;
|
||||||
|
|
||||||
[QueryProperty(nameof(ItemId), nameof(ItemId))]
|
|
||||||
public partial class NotePage : ContentPage
|
public partial class NotePage : ContentPage
|
||||||
{
|
{
|
||||||
public string ItemId
|
|
||||||
{
|
|
||||||
set => LoadNote(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotePage()
|
public NotePage()
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
string appDataPath = FileSystem.AppDataDirectory;
|
|
||||||
string randomFileName = $"{Path.GetRandomFileName()}.notes.txt";
|
|
||||||
|
|
||||||
LoadNote(Path.Combine(appDataPath, randomFileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void SaveButton_Clicked(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
if (BindingContext is Note note)
|
InitializeComponent();
|
||||||
File.WriteAllText(note.Filename, TextEditor.Text);
|
|
||||||
|
|
||||||
await Shell.Current.GoToAsync("..");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void DeleteButton_Clicked(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (BindingContext is Note note)
|
|
||||||
{
|
|
||||||
if (File.Exists(note.Filename))
|
|
||||||
File.Delete(note.Filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Shell.Current.GoToAsync("..");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadNote(string fileName)
|
|
||||||
{
|
|
||||||
Note noteModel = new Note();
|
|
||||||
noteModel.Filename = fileName;
|
|
||||||
|
|
||||||
if (File.Exists(fileName))
|
|
||||||
{
|
|
||||||
noteModel.Date = File.GetCreationTime(fileName);
|
|
||||||
noteModel.Text = File.ReadAllText(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
BindingContext = noteModel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user