在添加或删除

时间:2017-09-11 19:05:19

标签: c# xaml listview xamarin xamarin.forms

删除记录后,我很难刷新Xamarin ListView,或者从其他视图添加了一个。

我有一个视图(RaceList.xaml),它列出了从ViewModel获取的可观察集合中的种族。

RaceList.xaml.cs

using System.Collections.Generic;
using TechsportiseApp.API;
using TechsportiseApp.API.Models;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TechsportiseApp.MainUI.ViewModels;
using System;

namespace TechsportiseApp.MainUI
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RaceList : ContentPage
    {
        public List<Race> Races { get; set; }

        public RaceList()
        {
            InitializeComponent();

            var viewModel = new RaceListViewModel();
            BindingContext = viewModel;



            ToolbarItems.Add(new ToolbarItem("New", "Add.png", async () =>
            {
                await Navigation.PushAsync(new RaceNew());
            }));
        }

        public void OnDelete(object sender, EventArgs e)
        {
            var menuitem = ((MenuItem)sender);
            var stringraceid = menuitem.CommandParameter.ToString();
            int raceid = Int32.Parse(stringraceid);

            RacesAPI.DeleteRace(raceid);
            MessagingCenter.Send(this, "RaceListChanged");
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            RacesAPI.GetRaces();
            //LoadServerRegisteredCitizen is a method which i used to load items inside the listview        
        }

        async void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e)
        {
            if (e.Item == null)
                return;
            var race = e.Item as Race;

            await Navigation.PushAsync(new RaceView(race));
            //Deselect Item
            ((ListView)sender).SelectedItem = null;
        }


    }
}

RaceList.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TechsportiseApp.MainUI.RaceList"
             Title="Races">
    <!--SelectedItem="{Binding RaceSelected, Mode=TwoWay} "-->
    <ListView ItemsSource="{Binding Races}"
        ItemTapped="Handle_ItemTapped"
        SeparatorVisibility = "None"
        IsPullToRefreshEnabled="true" 
        RefreshCommand="{Binding RefreshCommand}" 
        IsRefreshing="{Binding IsBusy}">

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.ContextActions>
                       <MenuItem Clicked="OnDelete" CommandParameter="{Binding Id}" Text="Delete" IsDestructive="True" />
                    </ViewCell.ContextActions>
                    <StackLayout>
                        <Label Text="{Binding Name}"  />
                        <Label Text="{Binding RaceDate}" />
                        <BoxView Color="#B2B2B2" HeightRequest="1" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

RaceListViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RestSharp;
using TechsportiseApp.API.Models;
using Xamarin.Forms;
using TechsportiseApp.API;
using System.Windows.Input;
using System.Collections.ObjectModel;

namespace TechsportiseApp.MainUI.ViewModels
{
    public class RaceListViewModel : INotifyPropertyChanged
    {
        public RaceListViewModel()
        {
            _refreshCommand = new Command(RefreshList);

            MessagingCenter.Subscribe<RaceListViewModel>(this, "RaceListChanged", sender => {
                Races = RacesAPI.GetRaces();
                OnPropertyChanged("Id");
            });
        }

        public void RefreshList()
        {
            //Refreshes list on Pull to Refresh
           Races = RacesAPI.GetRaces();
        }

        int _id;
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    // trigger some action to take such as updating other labels or fields
                    OnPropertyChanged("Id");
                }
            }
        }

        int _name;
        public int Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (_name != value)
                {
                    _name = value;

                    // trigger some action to take such as updating other labels or fields
                    OnPropertyChanged("Name");
                }
            }
        }

        private ObservableCollection<Race> _races;
        public ObservableCollection<Race> Races
        {
            get
            {
                var racelist = RacesAPI.GetRaces();
                IsBusy = false;
                return racelist;
            }
            set
            {
                if (_races != value)
                {
                    _races = value;
                    // trigger some action to take such as updating other labels or fields
                    OnPropertyChanged("Races");
                }
            }
        }

        private Race _raceSelected;
        public Race RaceSelected
        {
            get
            {
                return RaceSelected;
            }
            set
            {
                if (RaceSelected != value)
                {
                    RaceSelected = value;
                    OnPropertyChanged("RaceSelected");
                }
            }
        }



        private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy == value)
                    return;

                _isBusy = value;
                OnPropertyChanged("IsBusy");
            }
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        Command _refreshCommand;
        public Command RefreshCommand
        {
            get
            {
                return _refreshCommand;
            }
        }
    }
}

按下工具栏中的“创建”按钮,这会将我带到一个新的视图,该视图显示一个空白表单,允许我填写新竞赛的数据。如果这是Saved,它会将JSON推送到我的API,如果成功,它会将它们重定向到编辑页面。

RaceNew.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             x:Class="TechsportiseApp.MainUI.RaceNew"
             Title="New Race">
    <ContentPage.Content>
    <ScrollView  Orientation = "Vertical" VerticalOptions="StartAndExpand">
    <StackLayout Padding="0,20,0,0">
        <Label x:Name="labelName" Text="Name" />
            <Entry x:Name="entryName"  />
        <Label x:Name="labelDescription" Text="Description" />
            <Editor x:Name="editorDescription"  />
       <Label x:Name="labelContactName" Text="Contact Name" />
            <Entry x:Name="entryContactName"  />
        <Label x:Name="labelContactNumber" Text="Contact Number" />
            <Entry x:Name="entryContactNumber" Keyboard="Telephone"  />
        <Label x:Name="labelContactEmail" Text="ContactEmail" />
            <Entry x:Name="entryContactEmail" Keyboard="Email"   />
        <Label x:Name="labelRaceDate" Text="Race Date" />
                <DatePicker x:Name="datepickerRaceDate" Date="{Binding Source={x:Static sys:DateTime.Now}" Format="ddd d MMMM yyyy" />
        <Label x:Name="labelRaceStartTime" Text="Race Time" />
                <TimePicker x:Name="timepickerRaceStartTime"  />
        <Label x:Name="labelMaxEntries" Text="Max Entries" />
                <Entry x:Name="entryMaxEntries"  Keyboard="Numeric"  />
        <Label x:Name="labelCurrentEntries" Text="Current Entries" />
                <Entry x:Name="entryCurrentEntries"  Keyboard="Numeric" />
        <Label x:Name="labelIsOpenForEntries" Text="Open For Entries" />
            <Switch x:Name="switchIsOpenForEntries"  />
        <Label x:Name="labelIsPublished" Text="Published" />
            <Switch x:Name="switchIsPublished"  />        
    </StackLayout>
    </ScrollView>
    </ContentPage.Content>
</ContentPage>

RaceNew.xaml.cs

using System;
using TechsportiseApp.API;
using TechsportiseApp.API.Models;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace TechsportiseApp.MainUI
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RaceNew : ContentPage
    {
        public RaceNew()
        {
            InitializeComponent();

            ToolbarItems.Add(new ToolbarItem("Create", "", async () =>

            {
                var saverace = new Race();
                saverace.ContactEmail = entryContactEmail.Text;
                saverace.ContactName = entryContactName.Text;
                saverace.ContactNumber = entryContactNumber.Text;
                saverace.CurrentEntries = 0;
                saverace.Description = editorDescription.Text;
                saverace.IsOpenForEntries = switchIsOpenForEntries.IsToggled;
                saverace.IsPublished = switchIsPublished.IsToggled;
                saverace.IsComplete = false;
                saverace.MaxEntries = System.Convert.ToInt32(entryMaxEntries.Text);
                saverace.Name = entryName.Text;
                saverace.RaceDate = datepickerRaceDate.Date;

                var timestring = string.Format("{0:00}:{1:00}:{2:00}", timepickerRaceStartTime.Time.Hours, timepickerRaceStartTime.Time.Minutes, timepickerRaceStartTime.Time.Seconds);
                saverace.RaceStartTime = timestring;

                var response = RacesAPI.CreateRace(saverace);
                if (response.Code == "Created")
                {
                    saverace.Id = response.ReturnedId;
                    Navigation.InsertPageBefore(new RaceView(saverace), this);
                    await Navigation.PopAsync();

                }
                //Error response
                else
                {
                    await DisplayAlert("Error: " + response.Code, "There has been an error creating your race. " + response.Content, "OK");
                }
            }));
        }


        async void OnBackButtonClicked(object sender, EventArgs e)
        {
            await Navigation.PopAsync();
        }
    }
}

在此页面中,我只需按“返回”按钮即可返回我的RaceList视图。

问题是,列表视图没有刷新 - 它没有注册添加新种族。

此外,在我的RaceList.xaml.cs中,您可以看到我还有一个正在使用的删除按钮。当我从列表中删除项目时,它也不会刷新!

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

覆盖Xamarin.Forms.Page.OnAppearing方法并调用ViewModel的RefreshList()方法。

RacelistViewModel Viewmodel =(RaceListViewModel)This.DataContext; ViewModel.RefreshList();

答案 1 :(得分:0)

我不知道,但是

public List<Race> Races { get; set; }

List,而不是ObservableCollection