gpt4 book ai didi

xamarin.android - 为什么向 MvxListView 派生对象添加 Header View 会破坏绑定(bind)过程?

转载 作者:行者123 更新时间:2023-12-04 15:22:31 24 4
gpt4 key购买 nike

我目前正在将 MvvmCross 用于新的应用程序项目,并且我正在尝试使用 MvxListView 显示标题 View 。阅读诸如 this 之类的讨论让我明白在设置适配器后无法添加 headerview,因此必须覆盖构造函数,以便在设置 MvxAdapter 之前添加 header 。这导致我实现了以下类:

public class HeaderListView : MvxListView
{
public FrameLayout HeaderFrame { get; set; }

public HeaderListView(Context context, IAttributeSet attrs)
: this(context, attrs, new MvxAdapter(context))
{
}

public HeaderListView(Context context, IAttributeSet attrs, IMvxAdapter adapter)
: base(context, attrs, null)
{
InitializeHeader(context);
// Note: Any calling derived class passing a null adapter is responsible for setting
// it's own itemTemplateId
if (adapter == null)
return;

var itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId(context, attrs);
adapter.ItemTemplateId = itemTemplateId;
Adapter = adapter;
}

private void InitializeHeader(Context context)
{
HeaderFrame = new FrameLayout(context);
AddHeaderView(HeaderFrame);
}
}

请特别注意第二个构造函数中的 InitializeHeader 调用。当我注释掉这一行时,测试应用程序启动正常,并且此 HeaderListView 的行为与标准 MvxListView 没有区别。但是,取消对该行的注释,你会看到一个空白的 ListView 和一些绑定(bind)错误:

MvxBind:Error: 10.86 Problem seen during binding execution for binding ItemsSource for Names - problem TargetInvocationException: Exception has been thrown by the target of an invocation.
02-02 23:33:01.948 I/mono-stdout( 2323): MvxBind:Error: 10.86 Problem seen during binding execution for binding ItemsSource for Names - problem TargetInvocationException: Exception has been thrown by the target of an invocation.
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0
02-02 23:33:01.948 I/mono-stdout( 2323): at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
02-02 23:33:01.948 I/mono-stdout( 2323): at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
02-02 23:33:01.958 I/mono-stdout( 2323): at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0
InnerException was NullReferenceException: Object reference not set to an instance of an object
at Cirrious.MvvmCross.Binding.Droid.Views.MvxListView.set_ItemsSource (IEnumerable value) [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
02-02 23:33:01.958 I/mono-stdout( 2323): at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0
02-02 23:33:01.968 I/mono-stdout( 2323): at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0
02-02 23:33:01.968 I/mono-stdout( 2323): InnerException was NullReferenceException: Object reference not set to an instance of an object
02-02 23:33:01.968 I/mono-stdout( 2323): at Cirrious.MvvmCross.Binding.Droid.Views.MvxListView.set_ItemsSource (IEnumerable value) [0x00000] in <filename unknown>:0
02-02 23:33:01.968 I/mono-stdout( 2323): at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0

我完全无法理解这个错误,因为导致它出现的唯一区别是我在分配适配器之前分配了一个标题 View ,但这与适配器没有任何关系。此错误的来源是什么,我该如何解决?

演示此问题的示例项目的完整源代码可用 on github .

最佳答案

原因与将页眉和页脚添加到 ListView 的怪异方式有关。当您将页眉或页脚添加到 ListView 时,当您为 ListView 设置适配器时,它会将您的适配器包装在一个返回页眉和页脚的 HeaderViewListAdapter 中,就好像它们只是您的适配器返回的实际行之前和之后的行一样。

MvxListView 失败的原因是它的 Adpater 属性,如下所示:

    public new IMvxAdapter Adapter
{
get { return base.Adapter as IMvxAdapter; }
set
{
// Code to copy ItemsSource and template ID

base.Adapter = value;
}
}

它不存储您提供给它的 IMvxAdapter 实例。它只是将其设置在 base.Adapter 中,并期望稍后获得 base.Adapter 时它将与之前设置的值相同。但当页眉和页脚添加到列表时,情况就不是这样了。您从 base.Adapter 返回的类将是一个 HeaderViewListAdapter,它包装了之前设置的 IMvxAdapter 实例。

作为 MvxList 的用户,没有好的方法来解决这个问题(除了复制和更改 MvxList)。 Stuart 的解决方法是不依赖 base.Adapter 作为 getter,而是将值存储到 setter 的字段中并从 getter 返回它。

关于xamarin.android - 为什么向 MvxListView 派生对象添加 Header View 会破坏绑定(bind)过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21519791/

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