MvxBindableLinearLayout ItemsSource绑定问题

时间:2013-04-10 17:20:39

标签: android binding android-linearlayout mvvmcross

我在设计活动时遇到了麻烦。

我正在尝试使用Mvx.MvxBindableLinearLayout,绑定到列表:A,B和c;

当我执行此绑定时,结果是: 一个 乙 C C 乙 甲

正确的是: 一个 乙 ç

有问题的代码是:

<?xml version="1.0" encoding="utf-8"?>

<ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:local="http://schemas.android.com/apk/res/m2uMobileSales.Droid"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     >

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:local="http://schemas.android.com/apk/res/m2uMobileSales.Droid"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:showDividers="none"
      android:layout_weight="1">

    <include
        layout="@layout/PageCommon_Titlebar" />

    <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tableLayout1"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:stretchColumns="1">
      <TableRow
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:id="@+id/tableLayout1"
          android:stretchColumns="1">
        <!--Customer Name-->
        <TextView
            android:id="@+id/CustomerName"
            android:layout_width="fill_parent"
             android:layout_height="wrap_content"
            android:textSize="30dp"
            android:layout_weight="1"
            local:MvxBind="{'Text':{'Path':'Customer.CustDetails.Name','Mode':'OneWay'}}" />
      </TableRow>

      <TableRow>
        <!--Detail Pages android:padding="12dp" -->

        <Mvx.MvxBindableLinearLayout
             android:padding="3dip"
             android:id="@+id/ClienteDetails"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
              android:divider="@null"
              android:dividerHeight="0dp"
              android:orientation="vertical"
              android:cacheColorHint="#00000000"
              android:layout_weight="1"
              local:MvxItemTemplate="@layout/listitem_clientdetailpages"
              local:MvxBind="{'ItemsSource':{'Path':'DetailPageViewModels'}}"/>

        <!--<Mvx.MvxBindableListView
            android:id="@+id/ClienteDetails"
            android:divider="@null"
            android:dividerHeight="0dp"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:cacheColorHint="#00000000"
            android:layout_weight="1"
            local:MvxItemTemplate="@layout/listitem_clientdetailpages"
            local:MvxBind="{'ItemsSource':{'Path':'DetailPageViewModels', 'Mode':'OneWay'}}" />-->
      </TableRow>

    </TableLayout>

  </LinearLayout>

</ScrollView>

如果我使用注释的Mvx.MvxBindableListView,我只能看到第一项。 目标是滚动所有元素而不是列表,作为android的定义。 克服了这个问题之后,我将在列表中有一个列表(DetailPageViewModels将包含几个元素,包括列表)。

我看过几篇帖子建议在ScrollView中插入所有元素。

我试过评论Mvx.MvxBindableLinearLayout,ScrollView和MvxBindableListView效果很好。如果我使用ScrollView,我只看到第一个元素。

我的目标是使用MvxBindableLinearLayout,因为我需要滚动整个页面和非元素。

listitem_clientdetailpages代码:

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/m2uMobileSales.Droid"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:showDividers="none"
    android:layout_weight="1">

  <!--Page Title-->
  <TextView
      android:id="@+id/detailpagetitle"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:textSize="24dp"
       android:padding="3dip"
      local:MvxBind="{'Text':{'Path':'Title','Mode':'OneWay'}}" >
  </TextView>

</LinearLayout>

我为这种困惑道歉。

感谢您的帮助和可用性。

2 个答案:

答案 0 :(得分:2)

我刚试过v3,这段代码按预期工作:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/com.cirrious.dailydilbert"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  >
   <Mvx.MvxLinearLayout
       android:orientation="vertical"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       local:MvxBind="ItemsSource Items;ItemClick ItemSelectedCommand"
       local:MvxItemTemplate="@layout/listitem_dilbert" />
</ScrollView>

对于您发布的代码,我无法在LinearLayout中看到任何问题。如果我能看到列表项的模板和viewmodel列表本身,可能会有所帮助。如果您认为有一个错误,那么请在某个地方发布一个简单的复制品,我会看一下 - 复制得越充分我就能越快看到它 - 即理想情况下在github repo上发布一个完整的解决方案 - 我可以下载然后运行它。

对于可绑定的ListView,我对属性android:layout_height="wrap_content"有点怀疑 - 怀疑可能无法正常工作。


更新,我也在Tutorial应用程序中尝试过用Page_MainMenuView.axml中的LinearLayout替换ListView:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/Tutorial.UI.Droid"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  >  
<Mvx.MvxLinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    local:MvxBind="ItemsSource Items;ItemClick ShowItemCommand"
    local:MvxItemTemplate="@layout/listitem_viewmodel"
  />
</ScrollView>

这完全显示 - 这是否也适用于您的设置?

如果确实如此,那么问题必须出现在您不包括的代码中......

答案 1 :(得分:1)

我是Paulo Dias的同事,我们刚刚知道发生了什么...... 问题在于创建MvxBindableLinearLayout

在构造函数中我们有

 Adapter = new MvxBindableListAdapterWithChangedEvent(context);
 Adapter.DataSetChanged += AdapterOnDataSetChanged;

在属性'Adapter'的'Set'中我们有

var existing = _adapter;
if (existing == value)
    return;

if (existing != null && value != null)
{
    existing.DataSetChanged -= AdapterOnDataSetChanged;
    value.ItemsSource = existing.ItemsSource;
    value.ItemTemplateId = existing.ItemTemplateId;
}

if (value != null)
{
    value.DataSetChanged += AdapterOnDataSetChanged;
}

第一次创建适配器时,DataSetChanged事件被订阅两次(在构造函数和适配器属性的集合中)。 如果我们有一个与MvxBindableLinearLayout绑定的应通知集合,则可能会出现问题。

现在棘手的部分......当我们在创建ui控件之后对绑定列表进行更改(即将新项添加到列表中)时,此错误仅“揭示自己”。如果我们在viewmodel中有一个“在构造函数中设置”然后永远不会更改的列表,那么永远不会触发DataSetChanged事件。另一方面,如果我们在创建ui之后添加项目(即您可以将命令绑定到按钮,将项目添加到列表中),则项目将在ui中重复...

为了解决这个问题,我们刚刚在MvxBindableLinearLayout构造函数中评论了DataSetChanged`正在订阅的行,并且所有内容都回落到了:)

        public MvxBindableLinearLayout(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            var itemTemplateId = MvxBindableListViewHelpers.ReadAttributeValue(context, attrs,
                                                                               MvxAndroidBindingResource.Instance
                                                                                                        .BindableListViewStylableGroupId,
                                                                               MvxAndroidBindingResource.Instance
                                                                                                        .BindableListItemTemplateId);
            Adapter = new MvxBindableListAdapterWithChangedEvent(context);
            Adapter.ItemTemplateId = itemTemplateId;
            //Adapter.DataSetChanged += AdapterOnDataSetChanged;
            this.ChildViewRemoved += OnChildViewRemoved;
        }

希望这有帮助!

ps:想知道为什么有人之前没有遇到过这个问题...

ps1:我们目前正在使用MvvmCross vNext。

ps2:我已改为Mvvmcross V3,问题仍然存在。我会在Github提出请求