I have this command to remove the Notes stored in the database, but even though it shows up, clicking on it doesn't have any affect. My thought was that this wasn't the proper way to bind this command. I tried various different ways of binding the RefreshCommand to the MenuItem but they either make it so that the app crashes when it refreshes or it just doesn't do its job, which is deleting the notes. Heres my code:
MyNotePage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:MyApp.Models"
xmlns:mvvm="clr-namespace:MvvmHelpers;assembly=MvvmHelpers"
xmlns:viewmodels="clr-namespace:MyApp.ViewModels"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="MyApp.MyNotePage"
x:DataType="viewmodels:MyNoteViewModel"
BackgroundColor="White">
<ContentPage.BindingContext>
<viewmodels:MyNoteViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<xct:ItemSelectedEventArgsConverter x:Key="ItemSelectedEventArgsConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Command="{Binding AddCommand}"/>
</ContentPage.ToolbarItems>
<ListView
BackgroundColor="Transparent"
CachingStrategy="RecycleElement"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
ItemsSource="{Binding Note}"
RefreshCommand="{Binding RefreshCommand}"
RefreshControlColor="DarkViolet"
SelectionMode="None"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Note">
<ViewCell>
<ViewCell.ContextActions>
<MenuItem x:DataType="viewmodels:MyNoteViewModel"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MyNoteViewModel}}, Path=RemoveCommand}"
CommandParameter="{Binding}"
IsDestructive="True"
Text="Delete"/>
</ViewCell.ContextActions>
<Grid Padding="10">
<Frame CornerRadius="20" HasShadow="True">
<StackLayout Orientation="Horizontal">
<StackLayout VerticalOptions="Center">
<Label
FontSize="Large"
Text="{Binding Name}"
VerticalOptions="Center"/>
<Label
FontSize="Small"
Text="{Binding Id}"
VerticalOptions="Center"/>
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
NoteService.cs
namespace MyApp.Services
{
public static class NoteService
{
static SQLiteAsyncConnection db;
static async Task Init()
{
if (db != null)
return;
{
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "MyData.db");
db = new SQLiteAsyncConnection(databasePath);
await db.CreateTableAsync<Note>();
}
}
public static async Task AddNote(string name)
{
await Init();
var note = new Note()
{
Name = name,
};
await db.InsertAsync(note);
}
public static async Task RemoveNote(int id)
{
await Init();
await db.DeleteAsync<Note>(id);
}
public static async Task<IEnumerable<Note>> GetNote()
{
await Init();
var note = await db.Table<Note>().ToListAsync();
return note;
}
}
}
MyNoteViewModel.cs
namespace MyApp.ViewModels
{
public class MyNoteViewModel : ViewModelBase
{
public ObservableRangeCollection<Note> Note { get; }
public AsyncCommand RefreshCommand { get; }
public AsyncCommand AddCommand { get; }
public AsyncCommand<Note> RemoveCommand { get; }
public MyNoteViewModel()
{
Note = new ObservableRangeCollection<Note>();
RefreshCommand = new AsyncCommand(Refresh);
AddCommand = new AsyncCommand(Add);
RemoveCommand = new AsyncCommand<Note>(Remove);
}
async Task Add()
{
var name = await App.Current.MainPage.DisplayPromptAsync("Notes", "Enter your notes here");
await NoteService.AddNote(name);
await Refresh();
}
async Task Remove(Note note)
{
await NoteService.RemoveNote(note.Id);
await Refresh();
}
async Task Refresh()
{
IsBusy = true;
await Task.Delay(2000);
Note.Clear();
var notes = await NoteService.GetNote();
Note.AddRange(notes);
IsBusy = false;
}
}
}
Thanks for the help
CodePudding user response:
try this
Command="{Binding BindingContext.RemoveCommand,
Source={x:Reference myNotePage}}"
where myNotePage
is your page's name
<ContentPage x:Name="myNotePage" ...