У меня возникла проблема: вызов функции 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());
}
}
}
Большая часть кода была удалена, чтобы сделать его максимально легким и читабельным, сохраняя при этом воспроизводимость, поэтому некоторые части кажутся избыточными или бесполезными.
Зафиксированный. Извини за это



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Добавьте следующий код в файл 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;. Когда я это добавил, все заработало отлично. Спасибо!
Я попытался воспроизвести ваш вопрос, но появились такие ошибки: Где вы определяете TempCoilNumber, NeedsToRender...? | Возвращаемое значение BeginScan() не установлено