Перемещение между файлами .xaml разрушает функцию javascript .focus() в MAUI (мобильный Android)

У меня возникла проблема: вызов функции javascript для фокусировки на определенном элементе не работает правильно сразу после перехода из одного файла .xaml в другой.

Поток начинается, когда выбран один из типов сканирования. Если выбран тип 1, он переходит на ScanningPage (другую страницу .xaml) и ожидает ввода, прежде чем вернуться обратно на MainPage. Затем вызывается ViewPopup(), и TempInputValue сначала равен False False, а затем переключается на True True textInput textInput. Однако элемент с идентификатором «textInput» на самом деле не фокусируется!

Когда выбран тип 2, он переходит прямо к ViewPopup(), а для TempInputValue устанавливаются те же значения, которые перечислены выше, но на этот раз, когда для него установлено значение True True textInput textInput, фактически отображается мобильная клавиатура.

Почему это происходит? Любая помощь приветствуется.

Код Блазора:

@page "/"
@inject IJSRuntime JSR

@if (CanSeePopup)
{
    <dialog open = "true" class = "center-div quantity-dialog">
        <h5>Enter Coil Number:</h5>
        <input @bind:event = "oninput" @bind:get = "TempInputValue" @bind:set = "InputReceivedInput" id = "textInput" />
        <div class = "center-div add-bottom-margin">
            <button @onclick = "ClosePopup">Finish</button>
            <button @onclick = "ClosePopup">Cancel</button>
        </div>
    </dialog>
}

<button @onclick = "TogglePage">Start Scanning Type 1</button>
<button @onclick = "ManualEntryCycle">Start Scanning Type 2</button>

<script>
    async function focusOnElement(elementId) {
        var element = document.getElementById(elementId);
        if (!!element) {
            element.focus();
        }
        return elementId + " " + document.activeElement.id;
    }
</script>

@code {
    private bool CanSeePopup = false;
    private bool NeedsToRender = false;
    private string TempInputValue = string.Empty;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        TempInputValue = NeedsToRender.ToString() + " " + CanSeePopup.ToString();
        await Task.Delay(600);
        if (NeedsToRender)
        {
            if (CanSeePopup) TempInputValue += await JSR.InvokeAsync<string>(identifier:"focusOnElement", args:"textInput");
            if (EnterRadiusForCoil) await JSR.InvokeVoidAsync("focusOnElement", "radiusInput");
            NeedsToRender = false;
            this.StateHasChanged();
        }
    }

    private void InputReceivedInput(string InputValue)
    {
        TempInputValue = InputValue.ToUpper();
    }

    private async void ClosePopup()
    {
        CanSeePopup = false;
        TempInputValue = string.Empty;
    }

    protected async Task TogglePage()
    {
        string ReturnValue = string.Empty;
        NavigationPage NavMain = Microsoft.Maui.Controls.Application.Current.MainPage as NavigationPage;
        MainPage MainPageRoot = NavMain.RootPage as MainPage;
        if (MainPageRoot == null) { }
        else
        {
            do
            {
                await Task.Delay(500);
                ReturnValue = await MainPageRoot.BeginScan();
            } while (!ReturnValue.Equals(string.Empty));
            if (ScanningPage.UserDesiresManualEntry)
            {
                ViewPopup();
                ScanningPage.UserDesiresManualEntry = false;
            }
        }
    }

    protected void ManualEntryCycle()
    {
        TempInputValue = string.Empty;
        ViewPopup();
    }

    private async void ViewPopup()
    {
        CanSeePopup = true;
        NeedsToRender = true;
    }

MainPage.xaml.cs:

public async Task<string> BeginScan()
{
    await Navigation.PushAsync(new ScanningPage());
    while (((NavigationPage)App.Current.MainPage).CurrentPage != this)
    {
        await Task.Delay(50);
    }
    if (ScanningPage.UserDesiresManualEntry)
    {
        return string.Empty;
    }
    return "null";
}

ScanningPage.xaml:

<ContentPage xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local = "clr-namespace:TestApp"
             x:Class = "TestApp.ScanningPage"
             Title = "Scan Page"
             BackgroundColor = "{DynamicResource PageBackgroundColor}"
             NavigationPage.HasBackButton = "False">

    <ContentPage.Content>
        <Grid VerticalOptions = "Fill" HorizontalOptions = "Fill">
            <Grid.RowDefinitions>
                <RowDefinition Height = "70
                               " />
                <RowDefinition Height = "*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width = "*" />
            </Grid.ColumnDefinitions>
            <Button Text = "Enter Value Manually" Clicked = "TempReturn" VerticalOptions = "Fill" HorizontalOptions = "Start" HeightRequest = "50"></Button>
        </Grid>
    </ContentPage.Content>
</ContentPage.Content>

СканнингПаже.xaml.cs:

namespace TestApp
{
    public partial class ScanningPage
    {
        public static bool UserDesiresManualEntry = false;

        public ScanningPage()
        { }

        public async void TempReturn(object sender, EventArgs E)
        {
            UserDesiresManualEntry = true;
            await Navigation.PopAsync();
        }
    }
}

Приложение.xaml.cs:

namespace TestApp
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new NavigationPage(new MainPage());
        }
    }
}

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

Я попытался воспроизвести ваш вопрос, но появились такие ошибки: Где вы определяете TempCoilNumber, NeedsToRender...? | Возвращаемое значение BeginScan() не установлено

Jianwei Sun - MSFT 16.07.2024 08:52

Зафиксированный. Извини за это

Frasher Gray 16.07.2024 13:08
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добавьте следующий код в файл MainPage.xaml.cs:

        protected override void OnAppearing()
        {
            base.OnAppearing();
 
            if (blazorWebView.Handler != null)
            {
#if ANDROID
                var androidweb = blazorWebView.Handler.PlatformView as Android.Webkit.WebView;
                androidweb.Focusable = true;
                androidweb.RequestFocus(Android.Views.FocusSearchDirection.Down);
                androidweb.PerformClick();
#endif
            }
        }

RequestFocus() может сосредоточить внимание на конкретном представлении или одному из его потомков, подсказав, в каком направлении движется фокус.

Хорошо, я понял, почему это не сработало с первого раза. В верхней части файла .xaml.cs должен быть знак @using Microsoft.Maui.Controls.PlatformConfiguration;. Когда я это добавил, все заработало отлично. Спасибо!

Frasher Gray 17.07.2024 14:19

Другие вопросы по теме