Xamarin:列表视图项ItemClick事件触发多次

时间:2016-08-31 00:41:28

标签: c# android xamarin

我正在开发一个应用程序,我使用Web服务从我的网站加载数据时,当我点击后退或下一个按钮时,它将再次加载来自Web服务的数据,然后在我的自定义PostAdapter类上加载这些数据然后加载该适配器到我的列表视图项

private async void LoadPosts(int year, int month){
    IPostService postService = new PostService();

    var posts = await postService.GetPosts(year, month);

    PostAdapter adapter = new PostAdapter(Activity, posts.ToList();

    _lstView.Adapter = adapter;

    _lstView.ItemClick += _lstView_ItemClick;
}

private void _lstView_ItemClick(object sender, AdapterView.ItemClickEventArgs e){
    var item = _lstView.GetItemAtPosition(e.Position).Cast<Post>();

    var bundle = new Bundle();
    bundle.PutInt("post_id", item.ID);

    var nextFragment = new PostDetailFragment { Arguments = bundle };

    var fragmentTransaction = this.Activity.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.content_frame, nextFragment).Commit();
}

private void _btnPrev_Click(object sender, EventArgs e){
    _selectedDate = _selectedDate.AddMonths(-1);

    LoadPosts(_selectedDate.Year, _selectedDate.Month);
}

现在,当我单击上一个按钮3次时,然后单击项目列表视图一次。它将触发列表视图项的项目单击事件的3倍。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您需要将此行移到LoadPosts方法之外,可能是等同于onCreate

_lstView.ItemClick += _lstView_ItemClick;

您获得3次事件点击的原因是每次加载帖子时,您都会向ListView添加另一个事件处理程序。

答案 1 :(得分:0)

在App.cs中注册事件,然后从MVVM中调用其他Dependencyservice方法。

例如:

步骤1:我具有一个事件( OnFileDownloaded )和一个方法( DownloadFile )的IDownloader界面。

第2步:在“ App.cs”中注册事件处理程序。

第3步:在MVVM类中调用“下载文件”功能。

文件下载后,“ OnFileDownloaded”事件将自动触发。

database

对于Android

public interface IDownloader
{
    void DownloadFile(string url, string folder);
    event EventHandler<DownloadEventArgs> OnFileDownloaded;
}

public class DownloadEventArgs : EventArgs
{
    public bool FileSaved = false;
    public string FilePath = string.Empty;

    public DownloadEventArgs(bool fileSaved, string filePath)
    {
        FileSaved = fileSaved;
        FilePath = filePath;
    }
}

对于iOS

[assembly: Dependency(typeof(Downloader_Droid))]
namespace Antsig.Droid.Services
{
    public class Downloader_Droid : IDownloader
    {
        public event EventHandler<DownloadEventArgs> OnFileDownloaded;
        string pathToNewFolder = string.Empty;
        public void DownloadFile(string url, string folder)
        {
            pathToNewFolder = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, folder);

            if(!Directory.Exists(pathToNewFolder)){Directory.CreateDirectory(pathToNewFolder);}

            try
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
                webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
            }
            catch (Exception)
            {
                if (OnFileDownloaded != null)
                    OnFileDownloaded.Invoke(this, new DownloadEventArgs(false,""));
            }
        }
        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (OnFileDownloaded != null)
                    OnFileDownloaded.Invoke(this, new DownloadEventArgs(false,""));
            }
            else
            {
                if (OnFileDownloaded != null)
                    OnFileDownloaded.Invoke(this, new DownloadEventArgs(true, pathToNewFolder));
            }
        }
    }
}

在App.cs文件中

[assembly: Dependency(typeof(Downloader_iOS))]
namespace Antsig.iOS.Services
{
    public class Downloader_iOS : IDownloader
    {
        public event EventHandler<DownloadEventArgs> OnFileDownloaded;
        string pathToNewFolder = string.Empty;

        public void DownloadFile(string url, string folder)
        {

            pathToNewFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), folder);

            try
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
                webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
            }
            catch (Exception)
            {
                if (OnFileDownloaded != null){  OnFileDownloaded.Invoke(this, new DownloadEventArgs(false,"")); }
            }
        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (OnFileDownloaded != null){ OnFileDownloaded.Invoke(this, new DownloadEventArgs(false,"")); }
            }
            else
            {
                if (OnFileDownloaded != null){ OnFileDownloaded.Invoke(this, new DownloadEventArgs(true, pathToNewFolder)); }
            }
        }
    }
}

在MVVM类文件中调用DependencyService

public partial class App : Application
{

    //Dependencyservice interface
    IDownloader downloader = null;

    protected override async void OnStart()
    {
        // Handle when your app starts
        downloader = DependencyService.Get<IDownloader>();
        downloader.OnFileDownloaded += OnFileDownloaded;

        base.OnResume();
    }

    private void OnFileDownloaded(object sender, DownloadEventArgs e)
    {
        if (e.FileSaved)
        {
            Device.BeginInvokeOnMainThread(async () =>
            {
                await Application.Current.MainPage.DisplayAlert("File Saved", "The PDF have downloaded.", "OK");
            });
        }
        else
        {
            Device.BeginInvokeOnMainThread(() => { DependencyService.Get<IToast>().Show("Error while saving the file"); });
        }
    }
}