我是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>
在后面的代码中,我们设置了ListView的ItemsSource
,并定义了搜索的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;
}
}
}
现在,您只需要带有文本的页面:Page1和Page2。
首先,我定义了一个InterfaceInterface1
,这些页面将实现该接口。这个接口的用途是定义一个单独的属性:PageText
。通过在Page1和Page2中实现此接口,我能够将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中将标签定义为Public
或Public static
。在第一种情况下,您必须保留对Page2 myPage2 = new Page2()
的引用,才能读取其公共标签(myPage2.myPublicLabel
(。在第二种情况下,只有Label仍然被引用,然后可以检索为Page2.mystaticLabel
。你自然首先必须检查标签是否已经分配,等等…
到目前为止,OP中描述的问题应该得到解决,但可能值得尝试一种不同的方法:
与其创建Page1、Page2等,您可能需要扩展您的对象(为ListView提供信息的对象,在上面的示例中称为Content
(,以包含String
属性ChapterText
,该属性包含要在其他页面中显示的文本。如果这样做,您可以创建一个通用的Page,其构造函数将其中一个对象作为参数,并使用ChapterText
作为Page的文本。这样,您就可以从SearchBar
执行搜索,而不必强制转换为Interface1
,而是直接在项的ChapterText
属性中执行。。。