Как открыть пользовательское диалоговое окно / всплывающее окно с помощью Xamarin.Форм?

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

Как открыть пользовательское диалоговое окно / всплывающее окно с помощью Xamarin.Форм?

любой пример кода будет оценен по достоинству?

спасибо заранее!

3 ответов


общая цель того, чего вы пытаетесь достичь, может быть достигнута с помощью PushModalAsync и PopModalAsync способы Xamarin.Формы навигация - это не совсем модально. Я объясню после небольшого фрагмента кода:-

        StackLayout objStackLayout = new StackLayout()
        {
        };
        //
        Button cmdButton_LaunchModalPage = new Button();
        cmdButton_LaunchModalPage.Text = "Launch Modal Window";
        objStackLayout.Children.Add(cmdButton_LaunchModalPage);
        //
        cmdButton_LaunchModalPage.Clicked += (async (o2, e2) =>
        {
            ContentPage objModalPage = new ContentPage();
            objModalPage.Content = await CreatePageContent_Page2();
            //
            await Navigation.PushModalAsync(objModalPage);
            //
            // Code will get executed immediately here before the page is dismissed above.
        });
        //
        return objStackLayout;



    private async Task<StackLayout> CreatePageContent_Page2()
    {
        StackLayout objStackLayout = new StackLayout()
        {
        };
        //
        Button cmdButton_CloseModalPage = new Button();
        cmdButton_CloseModalPage.Text = "Close";
        objStackLayout.Children.Add(cmdButton_CloseModalPage);
        //
        cmdButton_CloseModalPage.Clicked += ((o2, e2) =>
        {
            this.Navigation.PopModalAsync();
        });
        //
        return objStackLayout;
    }

проблема с выше, что

            await Navigation.PushModalAsync(objModalPage);

немедленно вернется после анимации.

хотя вы не можете взаимодействовать с предыдущей странице, как мы показываем новый NavigationPage С закрыть показано -родитель Навигация По Страницам по-прежнему выполняется за кулисами параллельно.

поэтому, если у вас были какие-либо таймеры или что-либо, выполняющее их, все равно будет вызвано, если вы их не остановите.

вы также можно использовать TaskCompletionSource подход, как указано в следующем сообщении также как я могу ждать увольнения модальной формы с помощью Xamarin.Форм?.

обратите внимание-что, хотя теперь вы можете ждут отображение 2-й страницы, а затем, когда эта страница отклонена, что позволяет продолжить выполнение кода на следующей строке-это еще не истинно модальная форма. Опять таймеры или что-нибудь исполняющее еще будет на родительской странице.

обновление 1:-

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

Если вы используете внешний контейнер, такие как решетки который поддерживает несколько дочерних элементов управления в одной ячейке, то вы сможете достичь того, что вы хотите.

вы также захотите использовать что-то вроде заполненный Box с прозрачностью, которая будет охватывать всю страницу Также, чтобы контролировать видимый, см. раздел, который окружает ваш внутренний раздел контента.


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

1. ModalPage и соответствующий рендерер

public class ModalPage : ContentPage { }

public class ModalPageRenderer : PageRenderer {
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        this.View.BackgroundColor = UIColor.Clear;
        this.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
    }

    public override void ViewDidLayoutSubviews()
    {
        base.ViewDidLayoutSubviews();
        SetElementSize (new Size (View.Bounds.Width, View.Bounds.Height));
    } 
}

2. HostPage

public class ModalHostPage : ContentPage, IModalHost
{
    #region IModalHost implementation

    public Task DisplayPageModal(Page page)
    {
        var displayEvent = DisplayPageModalRequested;

        Task completion = null;
        if (displayEvent != null)
        {
            var eventArgs = new DisplayPageModalRequestedEventArgs(page);
            displayEvent(this, eventArgs);
            completion = eventArgs.DisplayingPageTask;
        }

        // If there is no task, just create a new completed one
        return completion ?? Task.FromResult<object>(null);
    }

    #endregion

    public event EventHandler<DisplayPageModalRequestedEventArgs> DisplayPageModalRequested;

    public sealed class DisplayPageModalRequestedEventArgs : EventArgs
    {
        public Task DisplayingPageTask { get; set;}

        public Page PageToDisplay { get; }

        public DisplayPageModalRequestedEventArgs(Page modalPage)
        {
            PageToDisplay = modalPage;
        }
    }
}

3. Hostpage renderer

public class ModalHostPageRenderer: PageRenderer
{
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        if(e.OldElement as ModalHostPage != null)
        {
            var hostPage = (ModalHostPage)e.OldElement;
            hostPage.DisplayPageModalRequested -= OnDisplayPageModalRequested;
        }

        if (e.NewElement as ModalHostPage != null)
        {
            var hostPage = (ModalHostPage)e.NewElement;
            hostPage.DisplayPageModalRequested += OnDisplayPageModalRequested;
        }
    }

    void OnDisplayPageModalRequested(object sender, ModalHostPage.DisplayPageModalRequestedEventArgs e)
    {
        e.PageToDisplay.Parent = this.Element;
        var renderer = RendererFactory.GetRenderer (e.PageToDisplay);
        e.DisplayingPageTask = this.PresentViewControllerAsync(renderer.ViewController, true);
    }
}
это так же просто, как вызов await ModalHost.DisplayPageModal(new PopUpPage()); с вашей главной страницы или в этом конкретном случае из ViewModel позади.

Что Пит сказанное о PushModalAsync / PopModalAsync по-прежнему остается действительным и для этого решения (что, на мой взгляд, не является недостатком), но ваше всплывающее окно появится с прозрачным фоном.

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


я следовал выше подходу и обнаружил, что невозможно запустить на iOS 7. Я нашел эту библиотеку BTProgressHUD, которую вы можете изменять и использовать. Я использую его методы службой зависимостей. Фактическая библиотека для всплывающих окон. https://github.com/nicwise/BTProgressHUD

следующий пример использует BTProgressHUD библиотекой.

https://github.com/xximjasonxx/ScorePredictForms