2017-11-17 4 views
3

Ich habe eine Xamarin App, die eine Suchfunktion implementiert, in der Ergebnisse gruppiert werden. Daher habe ich eine gruppierte Listview verwendet.Clear ObservableCollection löst Ausnahme aus

private async void SearchRecipient() 
{ 
    IList<Recipient> recipients = null; 

    if (!string.IsNullOrWhiteSpace(RecipientSearched)) 
    { 
     recipients = await _service.GetRecipients(RecipientSearched.ToLower()); 

     FilteredRecipients.Clear(); 
     _userGroupedList.Clear(); 
     _officeGroupedList.Clear(); 

     if (recipients != null) 
     { 
      foreach (var r in recipients) 
      { 
       // Some logic to populate collections 
       _userGroupedList.Add(selectable); 
       _officeGroupedList.Add(selectable); 
      } 

      if (_userGroupedList.Count > 0) 
       FilteredRecipients.Add(_userGroupedList); 
      if (_officeGroupedList.Count > 0) 
       FilteredRecipients.Add(_officeGroupedList); 
     } 
    } 
} 

FilteredRecipients ist ein ObservableCollection, während _userGroupedList und _officeGroupedListList sind.

public SearchRecipientPageModel() 
{ 
    FilteredRecipients = new ObservableCollection<GroupedRecipientModel>(); 
    _userGroupedList = new GroupedRecipientModel("User"); 
    _officeGroupedList = new GroupedRecipientModel("Office"); 
} 

Suche funktioniert und Gruppierung als auch. Das Problem tritt auf, wenn ich eine Suche ein zweites Mal wiederholen und FilteredRecipients.Clear() wirft die folgende Ausnahme:

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index' 

UPDATE Probleme scheinen nur zu passieren, wenn einige Artikel des Ergebnisses mit einem Kontrollkästchen aktiviert ist. Ich denke, das liegt an meiner Checkbox-Renderer-Implementierung, weil ich Checkbox mit einem Switch ersetzt habe und es scheint zu funktionieren. Ich hatte einige Probleme, damit es im TwoWay-Modus funktioniert, aber vielleicht habe ich es nicht richtig gelöst.

public class CustomCheckBox : View 
{ 
    public bool Checked 
    { 
     get => (bool)GetValue(CheckedProperty); 
     set => SetValue(CheckedProperty, value); 
    } 

    public ICommand Command 
    { 
     get => (ICommand)GetValue(CommandProperty); 
     set => SetValue(CommandProperty, value); 
    } 

    public object CommandParameter 
    { 
     get => GetValue(CommandParameterProperty); 
     set => SetValue(CommandParameterProperty, value); 
    } 

    public static readonly BindableProperty CommandParameterProperty = 
           BindableProperty.Create("CommandParameter", typeof(object), typeof(CustomCheckBox), default(object)); 

    public static readonly BindableProperty CheckedProperty = 
           BindableProperty.Create("Checked", typeof(bool), typeof(CustomCheckBox), default(bool), propertyChanged: OnChecked); 

    public static readonly BindableProperty CommandProperty = 
       BindableProperty.Create("Command", typeof(ICommand), typeof(CustomCheckBox), default(ICommand)); 


    private static void OnChecked(BindableObject bindable, object oldValue, object newValue) 
    { 
     if (bindable is CustomCheckBox checkbox) 
     { 
      object parameter = checkbox.CommandParameter ?? newValue; 

      if (checkbox.Command != null && checkbox.Command.CanExecute(parameter)) 
       checkbox.Command.Execute(parameter); 
     } 
    } 
} 

Renderer

public class CustomCheckBoxRenderer : ViewRenderer<CustomCheckBox, CheckBox> 
{ 
    protected override void OnElementChanged(ElementChangedEventArgs<CustomCheckBox> e) 
    { 
     base.OnElementChanged(e); 
     if (Control == null && Element != null) 
      SetNativeControl(new CheckBox()); 

     if (Control != null) 
     {     
      Control.IsChecked = Element.Checked; 
      Control.Checked += (s, r) => { Element.Checked = true; }; 
      Control.Unchecked += (s, r) => { Element.Checked = false; }; 
     } 
    } 

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     base.OnElementPropertyChanged(sender, e); 

     if (e.PropertyName == nameof(Element.Checked)) 
      Control.IsChecked = Element.Checked; 
    } 
} 

Darüber hinaus untersuche ich noch einen Fehler dieser Renderer seit Checked Ereignis wird zweimal jedes Mal angehoben.

+2

Können Sie mehr Code posten? Haben Sie eine "SelectedItem" -Eigenschaft? Vielleicht kein "Clear" -Problem, aber etwas anderes, das mit "Clear" verbunden ist ... –

+0

Nun, mein XAML ist sehr einfach. Ich habe nur 'ItemsSource' und' IsGroupingEnabled' Eigenschaften eingestellt ... – user2297037

+0

Dem ersten Beitrag wurden einige Details hinzugefügt. – user2297037

Antwort

0

Try Code unten statt klar()

FilteredRecipients = new ObservableCollection<YourModel>(); 

bearbeiten

Lösung für aufgegebenes Ereignis wird zweimal jedes Mal angehoben.

if (e.OldElement != null) 
{ 
     Control.Checked -= (s, r) => { Element.Checked = true; }; 
     Control.Unchecked -= (s, r) => { Element.Checked = false; }; 
} 

if (e.NewElement != null) 
{ 
     Control.Checked += (s, r) => { Element.Checked = true; }; 
     Control.Unchecked += (s, r) => { Element.Checked = false; }; 
} 
+0

Funktioniert nicht ... Das Aufrufen des Konstruktors erfordert das Implementieren von NotifyPropertyChanged, also habe ich es hinzugefügt. Aber es wirft immer noch diese Ausnahme, obwohl diese Zeit Ausnahme durch den XAML-Code ausgelöst wird ... – user2297037

+0

Fügen Sie Ihre FilteredRecipients-Deklaration und Initialisierungscode ist es nützlich für die Hilfe –

+0

Mein erster Beitrag aktualisiert – user2297037

Verwandte Themen