Xamarin表单:联系人搜索不返回值



我已经使用这个博客从手机中提取了联系人。

我的代码:

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

我在这里上传了一个示例项目供参考。

这是因为您没有定义FilteredContacts的set方法。因此,价值永远不会改变。

修改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");
}
}
}

最新更新