Xamarin MVVM Удалить элемент списка просмотра с другой страницы - PullRequest
0 голосов
/ 09 октября 2019

Привет, новичок в форме Xamarin. У меня есть просмотр списка, и я могу получить информацию, когда элемент выбран аналогично шаблону, предоставленному в проекте xamarin для Visual Studio 2017.

Хотелось бы, чтобы шаблон был более полным, потому что добавление и обновление работают отлично, но явозникли проблемы при создании метода удаления. Данные удаляются из SQLite, но коллекция ObservableCollection не обновляется.

Я попытался скопировать аналогичную логику из добавления и обновления для удаления. Я попытался добавить другой метод центра сообщений в свой конструктор, но он не ударил при отладке, как при добавлении. Не уверен, что мне не хватает. Над моей головой все еще.

Вот список и его отлично работает

        <ContentPage.ToolbarItems>
        <ToolbarItem Text="-" Command="{Binding ExecuteDeleteAllCommand}"></ToolbarItem>
        <ToolbarItem Text="+" Clicked="InsertAuditClicked"></ToolbarItem>
    </ContentPage.ToolbarItems>
    <ContentPage.Padding>
        <OnIdiom>10, 10, 10, 10</OnIdiom>
    </ContentPage.Padding>
    <ContentPage.Content>
        <StackLayout>
            <ListView x:Name="AuditsListView"
                      ItemsSource="{Binding AuditsCollection}"
                      VerticalOptions="FillAndExpand"
                      HasUnevenRows="true"
                      RefreshCommand="{Binding LoadAuditsCommand}"
                      IsPullToRefreshEnabled="true"
                      IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                      CachingStrategy="RecycleElement"
                      ItemSelected="OnAuditSelected">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Grid>
                                <StackLayout Grid.Column="0">
                                    <!-- <Label Text="{Binding Id}"
                                       LineBreakMode="NoWrap"
                                       Style="{DynamicResource ListAuditTextStyle}"
                                       FontSize="16"></Label>-->
                                    <Label Text="{Binding AuditId}"
                                       Style="{DynamicResource ListAuditTextStyle}"
                                       FontSize="16"></Label>
                                    <Label Text="{Binding AuditCommand}"
                                       LineBreakMode="NoWrap"
                                       Style="{DynamicResource ListAuditDetailTextStyle}"
                                       FontSize="13"></Label>
                                </StackLayout>
                                <StackLayout Grid.Column="1" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand">
                                    <Label Text=">" FontSize="18"></Label>
                                </StackLayout>
                            </Grid>

                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>

Здесь код

    {
        AuditsViewModel ViewModel;

        public AuditsPage()
        {
            InitializeComponent();

            BindingContext = ViewModel = new AuditsViewModel();
        }

        async void OnAuditSelected(object s, SelectedItemChangedEventArgs e)
        {
            var m = e.SelectedItem as AuditModel;

            if (m == null)
                return;

            await Navigation.PushAsync(new AuditDetailPage(new AuditDetailViewModel(m))); // (new AuditDetailPage(new AuditDetailViewModel(m)));

            AuditsListView.SelectedItem = null;
        }

        async void InsertAuditClicked(object sender, EventArgs e)
        {

            await Navigation.PushModalAsync(new NavigationPage(new AuditNewPage()));

        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            if (ViewModel.AuditsCollection.Count == 0)
                ViewModel.LoadAuditsCommand.Execute(null);
        }


    }

Вот модель представления

namespace AuditTest.ViewModels
{
    public class AuditsViewModel : BaseViewModel
    {
        public ObservableCollection<AuditModel> AuditsCollection { get; set; }

        public Command LoadAuditsCommand { get; set; }

        public AuditsViewModel()
        {
            Title = "Browse";
            AuditsCollection = new ObservableCollection<AuditModel>();
            LoadAuditsCommand = new Command(async () => await ExecuteLoadAuditsCommand());

            MessagingCenter.Subscribe<AuditNewPage, AuditModel>(this, "AddAudit", async (o, a) =>
            {
                var n = a as AuditModel;
                AuditsCollection.Add(n);
                await App.MobileDataBase.InsertAuditAsync(n);
            });

            //MessagingCenter.Subscribe<AuditDetailPage, AuditModel>(this, "DeleteAudit", async (o, a) =>
            //{
            //    var n = a as AuditModel;
            //    AuditsCollection.Remove(n);
            //    await App.MobileDataBase.DeleteAuditAsync(n);


            //});

        }

        async Task ExecuteLoadAuditsCommand()
        {
            if (IsBusy)
                return;

            IsBusy = true;

            try
            {
                AuditsCollection.Clear();
                var a = await App.MobileDataBase.GetAuditsAsync(true); // var a = await DataSource.GetAuditsAsync(true);

                foreach (var i in a)
                {
                    AuditsCollection.Add(i);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }

    }
}

Получил панель инструментов с событием щелчка. Вот код

    using AuditTest.Models;
using Xamarin.Forms;
using AuditTest.Views;
using System.Threading.Tasks;

namespace AuditTest.ViewModels
{
    public class AuditDetailViewModel : BaseViewModel
    {
        public AuditModel AuditDetail { get; set; }

        public AuditDetailViewModel(AuditModel m = null)
        {

            Title = m.AuditId.ToString(); // m?.AuditId;
            AuditDetail = m;

        }

        public Command ExecuteEditAuditCommand
        {
            get
            {
                return new Command(async () =>
                {
                    await DataSource.UpdateAuditAsync(AuditDetail);
                });
            }
        }

        public Command ExecuteDeleteAuditCommand
        {
            get
            {
                return new Command(async () =>
                {
                    await App.MobileDataBase.DeleteAuditAsync(AuditDetail); // DataSource.DeleteAuditAsync(AuditDetail.AuditId));
                });
            }
        }

        public Task TestUpdateCommand()
        {
            Task<bool> tt = App.MobileDataBase.UpdateAuditAsync(AuditDetail);

            return tt;
        }

        public Task TestDeleteCommand()
        {
            Task<bool> tt = App.MobileDataBase.DeleteAuditAsync(AuditDetail);
            MessagingCenter.Send(this, "DeleteAudit", this.AuditDetail); // await ViewModel.ExecuteDeleteAuditCommand(); // App.MobileDataBase.DeleteAuditAsync();
            return tt;

        }
    }
}

Игра с различными свойствами и методами, но вот модель представления для страницы контента

    using AuditTest.Models;
using Xamarin.Forms;
using AuditTest.Views;
using System.Threading.Tasks;

namespace AuditTest.ViewModels
{
    public class AuditDetailViewModel : BaseViewModel
    {
        public AuditModel AuditDetail { get; set; }

        public AuditDetailViewModel(AuditModel m = null)
        {

            Title = m.AuditId.ToString(); // m?.AuditId;
            AuditDetail = m;

        }

        public Command ExecuteEditAuditCommand
        {
            get
            {
                return new Command(async () =>
                {
                    await DataSource.UpdateAuditAsync(AuditDetail);
                });
            }
        }

        public Command ExecuteDeleteAuditCommand
        {
            get
            {
                return new Command(async () =>
                {
                    await App.MobileDataBase.DeleteAuditAsync(AuditDetail); // DataSource.DeleteAuditAsync(AuditDetail.AuditId));
                });
            }
        }

        public Task TestUpdateCommand()
        {
            Task<bool> tt = App.MobileDataBase.UpdateAuditAsync(AuditDetail);

            return tt;
        }

        public Task TestDeleteCommand()
        {
            Task<bool> tt = App.MobileDataBase.DeleteAuditAsync(AuditDetail);
            MessagingCenter.Send(this, "DeleteAudit", this.AuditDetail); // await ViewModel.ExecuteDeleteAuditCommand(); // App.MobileDataBase.DeleteAuditAsync();
            return tt;

        }
    }
}

1 Ответ

0 голосов
/ 10 октября 2019

Fixed. Спасибо Джейсон, ты потрясающий! Теперь он работает.

Не комментировал и изменил подписку центра сообщений в конструкторе ViewModel так, чтобы он указывал на другую отправляющую ViewModel

MessagingCenter.Subscribe<AuditDetailViewModel, AuditModel>(this, "DeleteAudit", async (o, a) =>
            {
                var n = a as AuditModel;
                AuditsCollection.Remove(n);
                await App.MobileDataBase.DeleteAuditAsync(n);


            });

Открытый метод в другой ViewModel имеет это все еще

        public void MethodDeleteCommand()
        {
            MessagingCenter.Send(this, "DeleteAudit", this.AuditDetail);
        }
...