Как выполнить поиск текста на других страницах (метках) в Xamarin.Forms - PullRequest
0 голосов
/ 31 октября 2019

Я новичок в разработке Xamarin. Я надеюсь, что вы можете решить мою проблему в простом режиме.

У меня есть кроссплатформенное приложение, разработанное с помощью xamarin. На одной странице приложения я хочу дать возможность искать слово и перенаправлять пользователя на страницу, которую он хочет. Я опишу вам ситуацию.

У меня есть страница с представлением списка (listview.xaml). каждый элемент представления списка используется как кнопки для перехода на другие страницы (page1.xaml; page2.xaml; page3.xaml; и т. д.). на этих страницах есть текст (на этикетке). поэтому я хочу, чтобы, если я буду искать слово «пример» в listpage.xaml, я получу в качестве результатов все страницы, где существует слово «пример», и использую результаты, чтобы перейти к правильной странице, где находится слово «пример».

Пожалуйста, если можете, дайте мне простое решение. Спасибо.

это мой listview.xaml

<ContentPage.Content>
        <StackLayout Orientation="Vertical">
            <StackLayout Margin="10,10,0,0">
                <StackLayout BackgroundColor="#2B2B2B" Padding="0" Margin="-10,-10,0,0">
                <SearchBar TextColor="White" Placeholder="Cerca la parola chiave..." Margin="-5,0,0,0" />
               </StackLayout>
                <ListView ItemTapped="argomentilist_ItemTapped" x:Name="argomentilist" RefreshControlColor="#1F9F73">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Vertical" BackgroundColor="{Binding BackgroundColor}">
                                <Label Text="{Binding Capitolo}" Font="18" TextColor="Black"></Label>
                                <Label Text="{Binding Descrizione}" Font="14" TextColor="Gray"></Label>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
        </StackLayout>
    </ContentPage.Content>

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Отказ от ответственности:

Это просто способ выполнить требования, установленные в Исходном сообщении (ОП), и ни в коем случае не подразумевать, что код, который он включает, является наилучшим из возможных или предназначен для производства. кодЭТО ПРОСТО ПУТЬ , ЧТОБЫ ДОСТИГНУТЬ, ЧТО ТРЕБУЕТ ОП.


Давайте создадим Page ( ListView.xaml ) с ListView , который перечисляет пару пунктов, которые ссылаются на главы книги. Каждый элемент при нажатии запускает страницу с содержанием этой главы.

Кроме того, в верхней части этой ListView Page есть SearchBar: когдапри выполнении поиска приложение проверит, содержит ли какой-либо из страниц, на которые ссылаются элементы, искомый текст.

ListView.xaml:

<StackLayout>

    <SearchBar SearchButtonPressed="SearchBar_SearchButtonPressed" TextChanged="SearchBar_TextChanged"/>

    <ListView x:Name="listView"
              ItemTapped="listView_ItemTapped">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="{Binding Chapter}"
                          Detail="{Binding Description}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</StackLayout>

Находясь в коде позади, мы устанавливаем ItemsSource ListView и определяем EventHandlers для поиска (Бонус: обратите внимание на EventHandler SearchBar_TextChanged, чтобы вернуться ксписок оригиналов при очистке панели поиска!):

ListView.xaml.cs:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Xamarin.Forms;

namespace SearchContent
{
    public partial class ListView : ContentPage
    {

        ObservableCollection<Content> contents { get; set; }
        public ListView()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {

            base.OnAppearing();

            contents = new ObservableCollection<Content>()
            {
                new Content("Chapter 1", "Description of Chapter 1", new Page1()),
                new Content("Chapter 2", "Description of Chapter 2", new Page2()),
            };

            listView.ItemsSource = contents;

        }


        private void listView_ItemTapped(object sender, ItemTappedEventArgs e)
        {
            Navigation.PushAsync(((Content)e.Item).ChapterPage);
        }

        private void SearchBar_SearchButtonPressed(object sender, EventArgs e)
        {
            String textToSearch = ((SearchBar)sender).Text;

            var contentsFiltered = contents.Where(item => ((Interface1)item.ChapterPage).PageText.Contains(textToSearch));

            ObservableCollection<Content> newContents = new ObservableCollection<Content>(contentsFiltered);

            listView.ItemsSource = null;
            listView.ItemsSource = newContents;

        }

        private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
        {
            if(String.IsNullOrEmpty(e.NewTextValue))
            {
                listView.ItemsSource = null;
                listView.ItemsSource = contents;
            }
        }
    }


    public class Content
    {
        public String Chapter { get; set; }

        public String Description { get; set; }

        public Page ChapterPage { get; set; }

        public Content(String chapter, String description, Page chapterPage)
        {

            Chapter = chapter; 
            Description = description;
            ChapterPage = chapterPage;

        }

    }

}

Теперь вам просто нужны страницыс текстом: Page1 и Page2 .

Прежде всего я определяю Интерфейс Interface1, который будут реализованы на этих страницах. Этот интерфейс используется для определения одного свойства: PageText. Благодаря реализации этого интерфейса в Page1 и Page2 я смог преобразовать каждый элемент в ListView в Interface1 в EventHandler SearchBar_SearchButtonPressed in ListView.xaml.cs .

Interface1.cs :

interface Interface1
{
    string PageText { get; set; }
}

А теперь страницы:

Page1.xaml

<StackLayout>
    <Label Text="{Binding PageText}"
           VerticalOptions="CenterAndExpand" 
           HorizontalOptions="CenterAndExpand" />
</StackLayout>

Page1.xaml.cs :

public partial class Page1 : ContentPage,Interface1
{

    public String PageText { get; set; }

    public Page1()
    {

        PageText =
           "This is the display of the inquiry of Herodotus of Halicarnassus, " +
           "so that things done by man not be forgotten in time, and that great " +
           "and marvelous deeds, some displayed by the Hellenes, some by the " +
           "barbarians, not lose their glory, including among others what was the " +
           "cause of their waging war on each other. ";

        InitializeComponent();

        BindingContext = this;
    }

}

И аналогично

Page2.xaml

<StackLayout>
    <Label Text="{Binding PageText}"
           VerticalOptions="CenterAndExpand" 
           HorizontalOptions="CenterAndExpand" />
</StackLayout>

Page2.xaml.cs

public partial class Page2 : ContentPage, Interface1
{
    public String PageText { get; set; }

    public Page2()
    {
        PageText =
        "The Persian learned men say that the Phoenicians were the cause " +
        "of the dispute. These (they say) came to our seas from the sea " +
        "which is called Red,1 and having settled in the country which " +
        "they still occupy, at once began to make long voyages. Among other " +
        "places to which they carried Egyptian and Assyrian merchandise, " +
        "they came to Argos";

        InitializeComponent();

        BindingContext = this;
    }
}

Но что, если вы ДОЛЖНЫ читать сами ярлыки? Хорошо, это не очень хорошая практика (поскольку это означало бы, что вы сохраняете ссылки на эти объекты и занимаете ресурсы), и я не могу представить себе случай, когда это ДОЛЖНО быть.

Но если бы мне пришлось это сделать, я бы подумал, что можно было бы определить метки либо как Public, либо как Public static в Page2 . В первом случае вы должны сохранить ссылку на Page2 myPage2 = new Page2(), чтобы прочитать Public Label (myPage2.myPublicLabel). Во втором случае это только метка, на которую остается ссылка, и ее можно затем извлечь как Page2.mystaticLabel. Естественно, сначала нужно проверить, назначен ли ярлык и т. Д. ...


Пока что проблема, описанная в ОП, должна быть решена, тем не менее, возможно, стоит попробоватьдругой подход:

Вместо создания Page1 , Page2 и т. д. вы, возможно, захотите расширить ваши объекты (те, которые питают ListView и вызвал Content в моем примере выше), чтобы включить String свойство ChapterText, которое содержит текст, предназначенный для отображения на других страницах. Если это так, вы можете создать универсальный Page , конструктор которого принимает один из этих объектов в качестве параметра и использует ChapterText в качестве текста для Page . После этого вы можете выполнить поиск из SearchBar без приведения к Interface1, но непосредственно в свойстве ChapterText элементов ...

0 голосов
/ 31 октября 2019

я постараюсь вам помочь:)

<?xml version="1.0" encoding="utf-8" ?>  
 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
         xmlns:local="clr-namespace:crossplatformapp"  
         x:Class="crossplatformapp.MainPage">  

<StackLayout>  
    <SearchBar TextChanged="SearchBar_TextChanged"></SearchBar>  
    <ListView x:Name="list">  
        <ListView.ItemTemplate>  
            <DataTemplate>  
                <TextCell Text="{Binding Name}" Detail="{Binding Num}">   

                </TextCell>  
            </DataTemplate>  
        </ListView.ItemTemplate>  
    </ListView>  

</StackLayout>  

и

namespace crossplatformapp  
{  
public partial class MainPage : ContentPage  
{  
    public List<Contacts> tempdata;  
    public MainPage()  
    {  
        InitializeComponent();  
        data();  
        list.ItemsSource = tempdata;  

    }  

    public void data()  
    {  
        // all the temp data  
        tempdata = new List<Contacts> {  
            new Contacts(){ Name = "umair", Num = "2323423"},  
            new Contacts(){ Name = "saleh", Num = "23423"},  
            new Contacts(){ Name = "umair", Num = "233423423"},  
            new Contacts(){ Name = "sanat", Num = "2423"},  
            new Contacts(){ Name = "jawad", Num = "323423"},  
            new Contacts(){ Name = "shan", Num = "2323423"},  
            new Contacts(){ Name = "ahmed", Num = "2323423"},  
            new Contacts(){ Name = "abc", Num = "2323423"},  
            new Contacts(){ Name = "umair", Num = "2323423"},  
            new Contacts(){ Name = "etc", Num = "2323423"},  
        };  
    }  

    private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)  
    {  
        //thats all you need to make a search  

        if (string.IsNullOrEmpty(e.NewTextValue))  
        {  
            list.ItemsSource = tempdata;  
        }  

        else  
        {  
            list.ItemsSource = tempdata.Where(x => 
 x.Name.StartsWith(e.NewTextValue));  
        }  
    }  
}  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...