Вызов одной из дочерних страниц TabbedPage для доступа к тексту записи - PullRequest
0 голосов
/ 07 мая 2020

Я знаю: «Настоятельно рекомендуется использовать MVVM», но я просто пытаюсь понять и изучить структуру xamarin.forms. Итак, вот вопрос: мое приложение основано на TabbedPage, который состоит из двух NavigationPage:

<TabbedPage.Children >
    <NavigationPage Title="Search">
        <NavigationPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource">
                <On Platform="iOS" Value="tab_feed.png"/>
            </OnPlatform>
        </NavigationPage.Icon>
        <x:Arguments>
            <views:SearchPage />                
        </x:Arguments>
    </NavigationPage>

    <NavigationPage Title="Study">
        <NavigationPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource">
                <On Platform="iOS" Value="tab_about.png"/>
            </OnPlatform>
        </NavigationPage.Icon>
        <x:Arguments> <!---->
            <views:AboutPage />
        </x:Arguments>
    </NavigationPage>
</TabbedPage.Children>

Я пытаюсь вызвать дочерний элемент этой страницы с вкладками из метода, созданного в другой модели класса / представления, чтобы достичь Текст SearchBar:

    public async void AddToList()
    {
        var mp = (MainPage)App.Current.MainPage;
        var sp = (SearchPage)mp.Children[0]; /// exception related with casting is thrown.
        var Word = sp.WordSearchBar.Text;
        ...
    }

SearchPage определяется, как показано ниже. Итак, в чем проблема с созданием исключения литья. И как я могу получить доступ к тексту панели поиска (кроме привязок и MVVM)

public partial class SearchPage : ContentPage
{....}

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

mp.Children[0]; является разновидностью NavigationPage не SearchPage, поэтому вы получаете исключение приведения типов.

Один из способов добиться этого - создать свойство stati c в классе App:

public partial class `App` : Application
{
    public static AboutPage aboutPageInstance { get; set; }

    public App()
    {
        InitializeComponent();

        DependencyService.Register<MockDataStore>();
        MainPage = new MainPage();
    }
}

Затем назначьте значение в AboutPage и скажем, у вас есть метка с именем currentLabel в AboutPage:

public partial class AboutPage : ContentPage
{
    public Label currentLabel { get; set; }

    public AboutPage()
    {
        InitializeComponent();

        currentLabel = myLabel;
        App.aboutPageInstance = this;
    }
}

Затем вы можете получить доступ к метке в другой ContentPage:

async void AddToList(object sender, EventArgs e)
{

    if (App.aboutPageInstance != null)
    {
        AboutPage about = App.aboutPageInstance;

        about.currentLabel.Text = "kkk";
    }
}

MessagingCenter также является хорошим вариантом для связи между двумя разными ContentPages.

0 голосов
/ 07 мая 2020

В методе AddToList вы пытаетесь преобразовать первого дочернего элемента MainPage в SearchPage. В любом случае, в вашем XAML первый дочерний элемент в <TabbedPage.Children> - это NavigationPage, который, конечно, не является производным от вашего SearchPage, поэтому не может быть приведен, и выдается InvalidCastException.

Если вы действительно хотите сделать это таким образом (изучение MVVM прямо сейчас может быть полезно, но если вы действительно хотите изучить его трудным путем, это нормально для меня), вы бы должны получить доступ к NavigationPage, а затем к его CurrentPage

public async void AddToList()
{
    var mainPage = (MainPage)App.Current.MainPage;
    var navigationPage = (NavigationPage)mainPage.Children[0];

    if (navigationPage.CurrentPage is SearchPage searchPage)
    {
        var Word = searchPage.WordSearchBar.Text;
        ...
    }
}

Я ввел безопасное приведение с сопоставлением с образцом, потому что NavigationPage.CurrentPage может быть изменен (в отличие от MainPage и the NavigationPage), и мы не хотим, чтобы наше приложение выскакивало sh только потому, что на странице навигации активна неправильная страница.

Обратите внимание, что таким образом ваши страницы очень тесно связаны, что обычно считается не очень хорошей вещью. Даже без MVVM вам следует подумать о разделении страниц, например, с помощью MessagingCenter, см. Учебник Xamarin.Forms по слабосвязанным компонентам . В любом случае, вам следует подумать о внедрении интерфейсов для ваших страниц в этом случае, поскольку MessagingCenter требует типа отправителя, что снова приведет к некоторой жесткой связи. Отправка поискового текста в другой компонент может быть достигнута путем вызова

MessagingCenter.Send<ISearchPage, string>(this, MessengerKeys.SearchTextChanged, searchText);

Но что именно было бы разумным, сильно зависит от вашего приложения и может быть лучший способ.

...