gpt4 book ai didi

exception - 清除 ObservableCollection 抛出异常

转载 作者:行者123 更新时间:2023-12-04 16:05:16 26 4
gpt4 key购买 nike

我有一个 Xamarin 应用程序,它实现了对结果进行分组的搜索功能。因此我使用了分组 ListView 。

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);
}
}
}
FilteredRecipientsObservableCollection , 而 _userGroupedList_officeGroupedListList .
public SearchRecipientPageModel()
{
FilteredRecipients = new ObservableCollection<GroupedRecipientModel>();
_userGroupedList = new GroupedRecipientModel("User");
_officeGroupedList = new GroupedRecipientModel("Office");
}

搜索工作和分组也是如此。当我第二次重复搜索和 FilteredRecipients.Clear() 时,就会出现问题。抛出以下异常:
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'

更新
问题似乎只有在使用复选框选择结果的某些项目时才会发生。我认为是由于我的 Checkbox Renderer 实现,因为我用 Switch 替换了 Checkbox,它似乎可以工作。我在使其在双向模式绑定(bind)中工作时遇到了一些问题,但也许我没有正确修复它。
    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);
}
}
}

渲染器
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;
}
}

此外,我仍在调查此渲染器的错误,因为 Checked 事件每次都会引发两次。

最佳答案

可怕的是,这个错误在 2 年后仍然在 iOS ObservableCollection.Clear() 中出现! (android对此没有任何问题。)它很难重现,但我注意到它发生在一些异步方法和匿名函数中。 (我经常在我的 View 模型中使用这些命令)
为我解决它的部分解决方案是包含在 BeginInvokeOnMainThread() 中。

Device.BeginInvokeOnMainThread(() =>
{
FilteredRecipients.Clear();
});
我没有创建自定义 ObservableCollection,而是创建了一个扩展方法:
public static void SafeClear<T>(this ObservableCollection<T> observableCollection)
{
if(!MainThread.IsMainThread)
{
Device.BeginInvokeOnMainThread(() =>
{
while (observableCollection.Any())
{
ObservableCollection.RemoveAt(0);
}
});
}
else
{
while (observableCollection.Any())
{
ObservableCollection.RemoveAt(0);
}
}
}
所以在 OP 的例子中,他会像这样调用扩展方法:
FilteredRecipients.SafeClear();
_userGroupedList.SafeClear();
_officeGroupedList.SafeClear();
编辑 - 经过进一步测试, clear() 仍然因超出索引错误而崩溃。将@Павел Воронцов 的答案与扩展方法结合使用是我们最终采用的方法。

关于exception - 清除 ObservableCollection 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47347273/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com