Xamarin表单:在列表视图中执行搜索时,选定的项目将被清除 在Xaml中

问题描述

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

现在,我正在尝试添加联系人的选择。使用开关,我完成了选择。但是执行搜索操作时,选定的联系人正在清除。

xaml

<Switch
    Toggled="OnToggledEvent"
    HorizontalOptions="EndAndExpand"
    VerticalOptions="CenterAndExpand"/>

xaml.cs

public List<Contact> contactList;
public MainPage(IContactsService contactService)
{
    InitializeComponent();
    contactList = new List<Contact>();
    BindingContext = new ContactsViewModel(contactService);
}

void OnToggledEvent(object sender,EventArgs args)
{
    ViewCell cell = (sender as Xamarin.Forms.Switch).Parent.Parent as ViewCell;
    if (cell.BindingContext is Contact)
    {
        Contact contact = cell.BindingContext as Contact;
        if (contact != null)
        {
            if (contact != null && !contactList.Contains(contact))
            {
                contactList.Add(contact);
            }
            else if (contact != null && contactList.Contains(contact))
            {
                contactList.Remove(contact);
            }
        }
    }
    Debug.WriteLine("contactList:>>" + contactList.Count);
}

ContactsViewModel

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

在切换开关时,我会将选定的联系人添加到列表中。如果再次单击该开关,我将从列表中删除该联系人。但是问题是当搜索联系人时,已经选择的联系人会变得清晰。我尝试使用switch的IsToggled属性来解决此问题,但是没有运气。

我添加了一个示例项目here供参考。

解决方法

每次搜索时,itemsource都会更新,您应该在模型内部添加一个属性以记录开关的状态并实现INotifyPropertyChanged。

型号

public class Contact : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
    }

    public string Name { get; set; }
    public string Image { get; set; }
    public string[] Emails { get; set; }
    public string[] PhoneNumbers { get; set; }

    private bool isToggled;
    public bool IsToggled { 

        get {
            return isToggled;
        } set {
            isToggled = value;
            OnPropertyChanged();
        } 
    }
}

在Xaml中

<Switch  IsToggled="{Binding IsToggled} //... >"

如下修改OnToggledEvent方法

void OnToggledEvent(object sender,EventArgs args)
{


    var s = sender as Xamarin.Forms.Switch;
    var model = s.BindingContext as Contact;

    if(model != null)
    {
        if (model.IsToggled && !contactList.Contains(model))
        {
            contactList.Add(model);
        }
        else if (!model.IsToggled && contactList.Contains(model))
        {
            contactList.Remove(model);
        }
    Debug.WriteLine("contactList:>>" + contactList.Count);
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...