Xamarin 形成 PopupPage

Xamarin forms PopupPage

我正在使用 Rg.Plugins.Popup.Pages 作为弹出页面,当我按下一个按钮时,弹出窗口出现在页面中间,我在其中有一个 select 的单选按钮,当我完成时,我触摸透明背景退出。我的问题是,在后台页面中,我有一个标签,我需要根据我在页面的 onAppearing 方法的弹出页面中选择的内容进行修改,每当我触摸弹出页面的背景消失和背景的 onAppearing页面永远不会被调用!

按钮放在后台页面

 protected override void OnAppearing()
        {
            for (int i = 0; i < TestingClass.multiselection.Count; i++)
            {
                if (TestingClass.multiselection[i].is_selected)
                    btn.Text += TestingClass.multiselection[i].description;
            }
            base.OnAppearing();
        }

当弹出窗口出现时,我从静态 class 中获取值,值是这样保存的:

private void RadioButton_Clicked(object sender, System.EventArgs e)
        {
            var rb = sender as RadioButton;
            var selection = rb.BindingContext as multi_selection;
            if (selection != null && selection.is_selected == true)
            {
                selection.is_selected = false;
            }
            else
            if (selection != null && selection.is_selected == false)
            {
                selection.is_selected = true;
                TestingClass.multiselection.Add(selection);
            }
        }

根据平台的不同,OnApperearing 可能只被调用一次。也许您可以将其翻转并连接到弹出页面的 OnDisappearing 并使用它来更新您的值?

有两种方法(据我所知):

  1. 您可以在 PopupPage 中创建 EventHandler 并在初始化此 popupPage 时订阅它:

    MyPopupPage popup = new MyPopupPage();
    // Subscribe event
    popup.Save += SaveEventHandlerArgs;
    Navigation.PushPopupAsync(popup);
    

    在您的 popupPage 中选择一个值后,调用您的事件处理程序并将值作为参数传递。之后 SaveEventHandlerArgs 方法将被调用,在那里你可以得到你的价值并用它做你想做的事;

    Examples of using events

  2. 可以使用MessagingCenter。示例在 link.

希望对您有所帮助!

当您在视图中添加弹出窗口时,不会调用 OnApperearing 和 OnDisappearing。

Apple document中说:

viewWillAppear:

This method is called before the view controller's view is about to be added to a view hierarchy and before any animations are configured for showing the view.

Android中:

OnCreate

OnCreate is the first method to be called when an activity is created.

添加弹出窗口或删除弹出窗口既不是 create/remove 新视图也不是 add/remove 视图 to/from 层次结构。所以,这些生命周期方法不会在那个时候被调用。

解法:

关于弹窗选择后如何设置按钮的文字,我同意Денис Чорный的回答,我用代码说明一下。

1.Use eventHandle:

在弹出页面中,定义一个EventHandler:

public EventHandler SelectedStringChanged { get; set; }

在您的 RadioButton_Clicked 中,添加一行以调用 SelectedStringChanged:

    private void RadioButton_Clicked(object sender, System.EventArgs e)
    {
        var rb = sender as RadioButton;
        var selection = rb.BindingContext as multi_selection;
        if (selection != null && selection.is_selected == true)
        {
            selection.is_selected = false;
        }
        else
        if (selection != null && selection.is_selected == false)
        {
            selection.is_selected = true;
            TestingClass.multiselection.Add(selection);
        }

        //Add this line
        SelectedStringChanged(sender, e);
    }

在后台页面,创建一个方法来处理btn.text:

    private void Handle_SelectedStringChanged(object sender, EventArgs rags)
    {
        // ... your code
        for (int i = 0; i < TestingClass.multiselection.Count; i++)
        {
            if (TestingClass.multiselection[i].is_selected)
                btn.Text += TestingClass.multiselection[i].description;
        }
    }

弹出方法中,消费Handle_SelectedStringChanged方法:

    private async void OnOpenPupup(object sender, EventArgs e)
    {
        _loginPopup.SelectedStringChanged += Handle_SelectedStringChanged;

        await PopupNavigation.Instance.PushAsync(_loginPopup);
    }
  1. MessageingCenter 也可以。

后台页面中:

   MessagingCenter.Subscribe<MainPage>(this, "stringSelected", (sender) => {
          // do something whenever the "stringSelected" message is sent
            for (int i = 0; i<TestingClass.multiselection.Count; i++)
                {
                    if (TestingClass.multiselection[i].is_selected)
                    btn.Text += TestingClass.multiselection[i].description;
                }
        });

在你弹出的页面中:

  private void RadioButton_Clicked(object sender, System.EventArgs e)
    {
        var rb = sender as RadioButton;
        var selection = rb.BindingContext as multi_selection;
        if (selection != null && selection.is_selected == true)
        {
            selection.is_selected = false;
        }
        else
        if (selection != null && selection.is_selected == false)
        {
            selection.is_selected = true;
            TestingClass.multiselection.Add(selection);
        }

        MessagingCenter.Send<MainPage>(this, "stringSelected");

    }

参考:messaging-center