Xamarin 表单 parent 和 child 页面中的事件和委托

Events and Delegates in Xamarin forms parent and child pages

我需要一些帮助。我是事件和处理程序的新手,我想开始使用事件来解耦,但我很困惑。

我有一个 class,其中有一个在 OnAppearing 上填充的列表视图。但是,为了防止每次单击页面时发生 onAppearing,我加载了一次列表,然后我希望在通过使用事件从服务器添加或删除项目时将项目添加到列表或从列表中删除。

ListView 页面是我最喜欢的报纸文章链接的列表。单击这些 link 中的任何一个时,我将被重定向到一个 LinksDetailsPage,我在其中传递选定的 link,然后显示与 link.

相关的任何详细信息

总之...

我想在我的收藏夹列表中无缝添加或删除项目。因此,当我单击 LinksDetailsPage 中的 AddItem 或 RemoveItem 时,我希望将该项目删除或添加到 FavoritesPage 列表。之前我只是依靠 OnAppearing 来发挥它的魔力并更新收藏夹列表,但是从列表中删除项目会滞后,所以我希望它会在 even 被调用时立即删除或添加,而不是当页面在 OnAppearing 上加载。但是我认为我要么没有正确调用事件,要么我的订阅者没有正确订阅。从一开始,活动和代表就让我感到困惑。最重要的是,我的收藏夹列表是这样分组的,这也是我第一次使用分组列表。 查看我的代码:

订阅者 我的收藏夹页面:

 public FavoritesPage()
        {
            InitializeComponent();
           
        }
        protected override async void OnAppearing()
        {

            if (_isDataLoaded)
                return;

            _isDataLoaded = true;
            base.OnAppearing();
            await LoadFavorites();

        }

        private async Task LoadFavorites()
        {
            groups = new ObservableCollection<LinksTypeGroup<string, NewspaperLink>>();
           
            var links = await _db.GetAllFavorites();
            
                var linkType = await _manager.GetLinkCategories();
                foreach(var type in linkType)
                {
                   
                    var typegroup = links.FindAll(
                    delegate(NewspaperLink link)
                    {   
                        return link.iLinkTypeID == type.iLinkTypeID;
                    });
              
                    groups.Add(new LinksTypeGroup<string, NewspaperLink>(type.Title, typegroup));
              
                
                MyList.GroupDisplayBinding = new Binding("GroupKey");
                MyList.ItemsSource = groups;
               

            }
        }
 public void Listener(FavoritesPage P)
        {
            P.LinkAdded += Item_Added;
            P.LinkDeleted += Item_Deleted;
            
        }
void Item_Deleted(object sender, int e)
        {
            Console.WriteLine("Item_Deleted");
// remove item from groups ..see code above

        }

 void Item_Added(object sender, int e)
        {
            Console.WriteLine("Item_Added");
// add to groups ..see code above

        }

到目前为止我没有访问任何东西。

出版商 链接详情页面:

    private NewspaperLink _link;
    public event EventHandler< NewspaperLink> ItemAdded;
    public event EventHandler< NewspaperLink> ItemDeleted;

  public LinksDetailsPage(NewspaperLink link)
        {
           
            _link = link; 
            BindingContext = _link;
            InitializeComponent();
        }

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

            await LoadLink();
        }

        private async Task LoadLink()
        {
            var url = await db.ReturnRecipeLink(_link.iLinkID);
            
                    linkWebView.Source = url;
                
                  CheckifExists(_link);
            }
        }

  void AddLink(object sender, System.EventArgs e)
        {
            var link = BindingContext as NewspaperLink;
            db.InsertIntoMyList(_link);
            ItemAdded?.Invoke(this, link);
  
            
        }

   void  DeleteLink(object sender, System.EventArgs e)
        {

            var link = BindingContext as NewspaperLink;
             db.DeleteFromMyList(_link);
             ItemDeleted?.Invoke(this, link);
    
        }

有人可以指导我如何使这个均匀的过程起作用吗?

如果要使用 EventsLinksDetailsPage 应该声明如下:

public partial class LinksDetailsPage : ContentPage
{
    public event EventHandler<NewspaperLink> ItemAdded;
    public event EventHandler<NewspaperLink> ItemDeleted;
    public LinksDetailsPage()
    {
        InitializeComponent();
    }

    protected virtual void AddLink(NewspaperLink e)
    {
        EventHandler<NewspaperLink> handler = ItemAdded;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected virtual void DeleteLink( NewspaperLink e)
    {
        EventHandler<NewspaperLink> handler = ItemDeleted;
        if (handler != null)
        {
            handler(this, e);
        }
    }
     
    // Add click event
    private void Add_Clicked(object sender, EventArgs e)
    {
        AddLink(new NewspaperLink() {link="first link" });
    }

    // Delete click event
    private void Delete_Clicked(object sender, EventArgs e)
    {
        DeleteLink(new NewspaperLink() { link = "first link" });
    }
}

public class NewspaperLink : EventArgs
{
    public string link { get; set; }
}

然后你需要在导航到 LinksDetailsPage 页面时在 ListView 页面 中订阅它:

private async void Button_Clicked(object sender, EventArgs e)
{
    LinksDetailsPage detailPage = new LinksDetailsPage();
    detailPage.ItemAdded += DetailGridPage_ItemAdded;
    detailPage.ItemDeleted += DetailGridPage_ItemDeleted;
    await Navigation.PushModalAsync(detailGridPage);
}

private void DetailGridPage_ItemDeleted(object sender, NewspaperLink e)
{
    Console.WriteLine("The tlink was deleted : " + e.link);
}

private void DetailGridPage_ItemAdded(object sender, NewspaperLink e)
{
    Console.WriteLine("The link was added : "+e.link);
}

同样,如果要使用Delegate,只需要在List Page中声明如下:

public partial class ListViewPage : ContentPage
{
    public delegate void ItemAddedDelegate(NewspaperLink e);
    public delegate void ItemDeletedDelegate(NewspaperLink e);

    public ListViewPage()
    {
        InitializeComponent();
    }

    private async void Button_Clicked(object sender, EventArgs e)
    {
        ItemAddedDelegate itemAddedDelegate = AddMethod;
        ItemDeletedDelegate itemDeletedDelegate = DeleteMethod;
        DetailGridPage detailGridPage = new DetailGridPage(itemAddedDelegate, itemDeletedDelegate);
        await Navigation.PushModalAsync(detailGridPage);
    }

    public static void AddMethod(NewspaperLink item)
    {
        Console.WriteLine("Add" + item.link);
    }
    public static void DeleteMethod(NewspaperLink link)
    {
        Console.WriteLine("Delete" + item.link);
    }

}

然后在LinksDetailsPage中,可以将adddelete委托方法传递给ListViewPage

public partial class LinksDetailsPage : ContentPage
{
    private ListViewPage.ItemAddedDelegate itemAddedDelegate;
    private ListViewPage.ItemDeletedDelegate itemDeletedDelegate;
 
    public DetailGridPage()
    {
        InitializeComponent();
    }

    public LinksDetailsPage(ListViewPage.ItemAddedDelegate itemAddedDelegate, ListViewPage.ItemDeletedDelegate itemDeletedDelegate)
    {
        InitializeComponent();
        this.itemAddedDelegate = itemAddedDelegate;
        this.itemDeletedDelegate = itemDeletedDelegate;
    }
   
    // Add click event
    private void Add_Clicked(object sender, EventArgs e)
    {
        itemAddedDelegate(new NewspaperLink() { link = "first link" });
    }

    // Delete click event
    private void Delete_Clicked(object sender, EventArgs e)
    {
        itemDeletedDelegate(new NewspaperLink() { link = "first link" });
    }
}

public class NewspaperLink : EventArgs
{
    public string link { get; set; }
}

如果使用 MessageCenter,这应该是最方便的方法。

只有 Subscribe 它在 ListView 页面:

public ListViewPage()
{
    InitializeComponent();

    MessagingCenter.Subscribe<object, NewspaperLink>(this, "Add", async (sender, arg) =>
    {
        await DisplayAlert("Message received", "arg=" + arg.link, "OK");
    });

    MessagingCenter.Subscribe<object, NewspaperLink>(this, "Delete", async (sender, arg) =>
    {
        await DisplayAlert("Message received", "arg=" + arg.link, "OK");
    });
}

并在LinksDetailsPage发送消息如下:

// Add click event
private void Add_Clicked(object sender, EventArgs e)
{
    NewspaperLink newspaperLink= new NewspaperLink() { link = "first link" };
    MessagingCenter.Send<object, NewspaperLink>(this, "Add", newspaperLink);
}
// Delete click event
private void Delete_Clicked(object sender, EventArgs e)
{
    NewspaperLink newspaperLink = new NewspaperLink() { link = "first link" };
    MessagingCenter.Send<object, NewspaperLink>(this, "Delete", newspaperLink);
}