如何在Xamarin.Forms中对其他页面(标签)执行文本搜索



我是Xamarin开发的新手。我希望你能用简单的方式解决我的问题。

我有一个用xamarin开发的跨平台应用程序。在应用程序的一个页面中,我想提供搜索单词并将用户重定向到他想要的页面的可能性。我会给你描述一下情况。

我有一个带有列表视图的页面(listview.xaml(。列表视图的每一项都像按钮一样用于其他页面(page1.xaml;page2.xaml;page3.xaml;etc.(。在这些页面中有一些文本(在标签中(。所以我想,如果我在listpage.xaml中搜索单词"example",我会收到单词"example"存在的所有页面作为结果,并使用结果导航到单词"sample"所在的正确页面。

如果可以的话,请给我一个简单的解决方案。谢谢

这是我的列表视图.xam

<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>

我会尽力帮助您:(

<?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));  
}  
}  
}  

免责声明:

这只是实现Original Post(OP(中设置的要求的一种方式,并不意味着它所涉及的代码是最好的,或者旨在成为类似生产的代码。这只是实现OP要求的一种方式。


让我们创建一个页面(ListView.xaml(,其中包含一个列出了一本书的章节的ListView。单击每个项目时,都会启动一个包含该章节内容的页面。

此外,在ListView页面的顶部有一个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>

在后面的代码中,我们设置了ListViewItemsSource,并定义了搜索的EventHandlers(额外的好处:当您清除搜索栏时,请注意EventHandlerSearchBar_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;
}
}
}

现在,您只需要带有文本的页面:Page1Page2

首先,我定义了一个InterfaceInterface1,这些页面将实现该接口。这个接口的用途是定义一个单独的属性:PageText。通过在Page1Page2中实现此接口,我能够将ListView的每个项强制转换为ListView.xam.cs事件处理程序SearchBar_SearchButtonPressed中的Interface1

接口1.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;
}
}

但如果你必须自己阅读标签呢好吧,这不是一个好的做法(因为这意味着你要保留那些被引用和占用资源的对象(,我无法想象会有这样的情况。

但如果必须这样做,我认为一种方法是在Page2中将标签定义为PublicPublic static。在第一种情况下,您必须保留对Page2 myPage2 = new Page2()的引用,才能读取其公共标签(myPage2.myPublicLabel(。在第二种情况下,只有Label仍然被引用,然后可以检索为Page2.mystaticLabel。你自然首先必须检查标签是否已经分配,等等…


到目前为止,OP中描述的问题应该得到解决,但可能值得尝试一种不同的方法:

与其创建Page1Page2等,您可能需要扩展您的对象(为ListView提供信息的对象,在上面的示例中称为Content(,以包含String属性ChapterText,该属性包含要在其他页面中显示的文本。如果这样做,您可以创建一个通用的Page,其构造函数将其中一个对象作为参数,并使用ChapterText作为Page的文本。这样,您就可以从SearchBar执行搜索,而不必强制转换为Interface1,而是直接在项的ChapterText属性中执行。。。

最新更新