如何解决Xamarin形式:联系人搜索不返回任何值
我已经使用this博客从手机中提取了联系人。
我的代码:
XAML
<StackLayout>
<SearchBar x:Name="filterText"
HeightRequest="40"
Text="{Binding SearchText}" />
<ListView ItemsSource="{Binding FilteredContacts}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10"
Orientation="Horizontal">
<Image Source="{Binding Image}"
VerticalOptions="Center"
x:Name="image"
Aspect="AspectFit"
HeightRequest="60"/>
<StackLayout VerticalOptions="Center">
<Label Text="{Binding Name}"
FontAttributes="Bold"/>
<Label Text="{Binding PhoneNumbers[0]}"/>
<Label Text="{Binding Emails[0]}"/>
</StackLayout>
<Switch
Toggled="OnToggledEvent"
HorizontalOptions="EndAndExpand"
VerticalOptions="CenterAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
视图模型
public class MainViewModel: INotifyPropertyChanged
{
IContactsService _contactService;
public event PropertyChangedEventHandler PropertyChanged;
public string Title => "Contacts";
public string SearchText { get; set; }
public ObservableCollection<Contact> Contacts { get; set; }
public ObservableCollection<Contact> FilteredContacts
{
get
{
return string.IsNullOrEmpty(SearchText) ? Contacts : new ObservableCollection<Contact>(Contacts?.ToList()?.Where(s => !string.IsNullOrEmpty(s.Name) && s.Name.ToLower().Contains(SearchText.ToLower())));
}
}
public MainViewModel(IContactsService contactService)
{
_contactService = contactService;
Contacts = new ObservableCollection<Contact>();
Xamarin.Forms.BindingBase.EnableCollectionSynchronization(Contacts,null,ObservableCollectionCallback);
_contactService.OnContactLoaded += OnContactLoaded;
LoadContacts();
}
void ObservableCollectionCallback(IEnumerable collection,object context,Action accessMethod,bool writeAccess)
{
// `lock` ensures that only one thread access the collection at a time
lock (collection)
{
accessMethod?.Invoke();
}
}
private void OnContactLoaded(object sender,ContactEventArgs e)
{
Contacts.Add(e.Contact);
}
async Task LoadContacts()
{
try
{
await _contactService.RetrieveContactsAsync();
}
catch (TaskCanceledException)
{
Console.WriteLine("Task was cancelled");
}
}
}
联系人和IContactsService
public class Contact
{
public string Name { get; set; }
public string Image { get; set; }
public string[] Emails { get; set; }
public string[] PhoneNumbers { get; set; }
}
public class ContactEventArgs : EventArgs
{
public Contact Contact { get; }
public ContactEventArgs(Contact contact)
{
Contact = contact;
}
}
public interface IContactsService
{
event EventHandler<ContactEventArgs> OnContactLoaded;
bool IsLoading { get; }
Task<IList<Contact>> RetrieveContactsAsync(CancellationToken? token = null);
}
我的问题是联系人中的搜索功能未返回任何数据。
Viewmodel中的搜索代码
public ObservableCollection<Contact> FilteredContacts
{
get
{
return string.IsNullOrEmpty(SearchText) ? Contacts : new ObservableCollection<Contact>(Contacts?.ToList()?.Where(s => !string.IsNullOrEmpty(s.Name) && s.Name.ToLower().Contains(SearchText.ToLower())));
}
}
我已经上传了一个示例项目here供参考。
解决方法
那是因为您没有定义 FilteredContacts 的设置方法。因此,该值将永远不会更改。
按如下所示修改ViewModel的代码
public class ContactsViewModel : INotifyPropertyChanged
{
IContactsService _contactService;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
public string Title => "Contacts";
string search;
public string SearchText {
get { return search; }
set {
if(search!=value)
{
search = value;
OnPropertyChanged("SearchText");
if (string.IsNullOrEmpty(SearchText))
{
FilteredContacts = new ObservableCollection<Contact>(Contacts);
}
else
{
FilteredContacts = new ObservableCollection<Contact>(Contacts?.ToList()?.Where(s => !string.IsNullOrEmpty(s.Name) && s.Name.ToLower().Contains(SearchText.ToLower())));
}
}
}
}
public ObservableCollection<Contact> Contacts { get; set; }
ObservableCollection<Contact> filteredContacts;
public ObservableCollection<Contact> FilteredContacts
{
get { return filteredContacts; }
set {
if(filteredContacts!=value)
{
filteredContacts = value;
OnPropertyChanged("FilteredContacts");
}
}
}
public ContactsViewModel(IContactsService contactService)
{
_contactService = contactService;
Contacts = new ObservableCollection<Contact>();
Xamarin.Forms.BindingBase.EnableCollectionSynchronization(Contacts,null,ObservableCollectionCallback);
_contactService.OnContactLoaded += OnContactLoaded;
LoadContacts();
FilteredContacts = Contacts;
}
void ObservableCollectionCallback(IEnumerable collection,object context,Action accessMethod,bool writeAccess)
{
// `lock` ensures that only one thread access the collection at a time
lock (collection)
{
accessMethod?.Invoke();
}
}
private void OnContactLoaded(object sender,ContactEventArgs e)
{
Contacts.Add(e.Contact);
}
async Task LoadContacts()
{
try
{
await _contactService.RetrieveContactsAsync();
}
catch (TaskCanceledException)
{
Console.WriteLine("Task was cancelled");
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。