Я хочу установить фокус на SearchBar, когда он появится. Проблема в том, что SearchBar находится внутри всплывающего окна, и мне нужно получить к нему доступ из ViewModel.
Стандартным способом я бы использовал
Xamarin.Forms.SearchBar tmp_SearchBar = this.Page.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
но это уже не работает.
Вот XAML
<sfPopup:SfPopupLayout x:Name = "fro_Popup_NewItem" Opened = "fro_Popup_NewItem_Opened" Grid.Row = "1" HorizontalOptions = "Center" VerticalOptions = "Center" BackgroundColor = "Black">
<sfPopup:SfPopupLayout.PopupView>
<sfPopup:PopupView BackgroundColor = "Black" WidthRequest = "400" HeightRequest = "100" ShowFooter = "False" ShowHeader = "False">
<sfPopup:PopupView.ContentTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
</Grid.RowDefinitions>
<!--Search bar-->
<Grid Grid.Row = "0" HorizontalOptions = "Center" VerticalOptions = "Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "*" />
<ColumnDefinition Width = "Auto" />
</Grid.ColumnDefinitions>
<SearchBar x:Name = "fro_SearchBar_NewItem"
Grid.Column = "0"
Text = "{Binding SearchText_Popup, Mode=TwoWay}"
SearchCommand = "{Binding SearchCommand}"
Placeholder = "Find"
CancelButtonColor = "White"
TextColor = "White"
PlaceholderColor = "Gray"/>
</Grid>
</Grid>
</DataTemplate>
</sfPopup:PopupView.ContentTemplate>
</sfPopup:PopupView>
</sfPopup:SfPopupLayout.PopupView>
</sfPopup:SfPopupLayout>
Вложенный FindByName тоже не работает.
Syncfusion.XForms.PopupLayout.SfPopupLayout tmp_Popup = _Page.FindByName("fro_Popup_NewItem") as Syncfusion.XForms.PopupLayout.SfPopupLayout;
Xamarin.Forms.SearchBar tmp_SearchBar = tmp_Popup.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
Спасибо
да, я мог бы использовать событие «Открыто» всплывающего окна, но все же, как получить доступ к окну поиска из этого?
Дайте строке поиска x: Name, затем используйте ее в функции «При появлении» кода, стоящего за всплывающим окном.
Это то, что я сделал, но это ноль. private void fro_Popup_NewItem_Opened (отправитель объекта, EventArgs e) { var searchbar = fro_Popup_NewItem.FindByName («fro_SearchBar_NewItem»); панель поиска = this.FindByName("fro_SearchBar_NewItem"); }
Вы можете использовать Задача, чтобы открыть новый поток для завершения этой операции в коде программной части.
Xaml:
<SearchBar x:Name = "fro_SearchBar_NewItem" Placeholder = "...." BackgroundColor = "White"/>
Код позади:
public partial class PagePop : Popup
{
public PagePop()
{
InitializeComponent();
Task.Run(() => myTask());//Create and start the thread
}
private void myTask()
{
Thread.Sleep(300);
fro_SearchBar_NewItem.Focus();
}
}
Не могли бы вы помочь подтвердить, полезно ли решение для вашего вопроса? Если да, отметьте его как ответ, так как оно полезно для других, кто сталкивается с той же проблемой.
да, оф. Я отсутствовал несколько дней.
Где я должен поместить этот класс PagePop? Я попытался создать собственный элемент управления, страницу содержимого, на которой размещается всплывающее окно, но ни один из них не работает.
Вы, ребята, явно упускаете суть проблемы, я знаю, как получить доступ к элементам управления из кода программной части (страница содержимого). Я не знаю, как получить доступ к элементу управления, который находится внутри другого элемента управления на странице содержимого, в данном случае SearchBar внутри всплывающего окна. Я не могу ссылаться на элементы управления со страницы содержимого, которые размещены внутри всплывающего окна. Я много искал по этой теме, и я не мог найти ничего полезного.
Я продвинулся немного вперед, но я еще не в конце. Я мог бы создать страницу XAML для всего всплывающего окна, а затем я могу использовать программный код всплывающего окна для работы с его элементами управления, но у меня есть аргументы в конструкторе PopupPage, и я не могу использовать его таким образом в XAML ContentPage. В нем говорится: тип «PopupPage» не может использоваться в качестве элемента объекта, поскольку он не является общедоступным или не определяет общедоступный конструктор без параметров или преобразователь типов.
Кажется, это было не так уж далеко от правильного направления, на самом деле ни один из комментариев.
Syncfusion.XForms.PopupLayout.SfPopupLayout tmp_Popup = _Page.FindByName("fro_Popup_NewItem") as Syncfusion.XForms.PopupLayout.SfPopupLayout;
Xamarin.Forms.SearchBar tmp_SearchBar = tmp_Popup.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
но я нашел тот, который работает, и мне не нужно создавать отдельный XAML для всплывающего окна.
private void fro_Popup_NewItem_Opened(object sender, EventArgs e)
{
try
{
var nativeObject = (object)fro_Popup_NewItem.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("NativeObject")).GetValue(fro_Popup_NewItem);
var formsPopupviewContentTemplate = nativeObject.GetType().GetRuntimeFields().FirstOrDefault(x => x.Name.Equals("formsPopupViewContentTemplate")).GetValue(nativeObject);
var SearchBar = (formsPopupviewContentTemplate as Grid).FindByName<SearchBar>("fro_SearchBar_NewItem");
SearchBar?.Focus();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Спасибо за помощь, всем.
во-первых, вам действительно никогда не нужно использовать
FindByName
напрямую. Во-вторых, если вы используете MVVM, вам не следует пытаться получить прямой доступ к представлению из виртуальной машины — для этого и нужна привязка данных. Если вы просто пытаетесь установить фокус, это можно сделать в коде позади. SfPopup имеет несколько событий жизненного цикла, которые вы можете использовать для этого.