9

ExpandableListViews の機能または類似の機能が Mvvmmcross フレームワーク内に潜んでいるのか、それともこのタイプのコントロールはマルチ プラットフォームの要件には適用できないのでしょうか。http://deapsquatter.blogspot.com/2013/02/mvvmcrossdeapextensions.htmlにある機能は 優れていますが、展開/折りたたみ機能が利用できるかどうかはわかりません。

ポインタ/サンプルコードをいただければ幸いです

4

2 に答える 2

6

これはそれについてです(Deepsqautterのコードに配置しました)。コードを整理した後、便利な場所に配置するか、mvvmcross 自体に追加するのに役立つかもしれません...

景色:

public class BindableExpandableListView : ExpandableListView
    {
        public BindableExpandableListView(Context context, IAttributeSet attrs)
            : this(context, attrs, new BindableExpandableListAdapter(context))
        {
        }
    public BindableExpandableListView(Context context, IAttributeSet attrs, BindableExpandableListAdapter adapter)
        : base(context, attrs)
    {
        var groupTemplateId = MvxAttributeHelpers.ReadAttributeValue(context, attrs,
                                                                           MvxAndroidBindingResource.Instance
                                                                            .ListViewStylableGroupId,
                                                                           AndroidBindingResource.Instance
                                                                           .BindableListGroupItemTemplateId);
 
        var itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId(context, attrs);
        SetAdapter(adapter);
        adapter.GroupTemplateId = groupTemplateId;
        adapter.ItemTemplateId = itemTemplateId;
    }

    // An expandableListView has ExpandableListAdapter as propertyname, but Adapter still exists but is always null.
    protected BindableExpandableListAdapter ThisAdapter { get { return ExpandableListAdapter as BindableExpandableListAdapter; } }

    

    private IEnumerable _itemsSource;
    [MvxSetToNullAfterBinding]
    public virtual IEnumerable ItemsSource
    {
        get { return ThisAdapter.ItemsSource; }
        set { ThisAdapter.ItemsSource = value; }
    }

    public int ItemTemplateId
    {
        get { return ThisAdapter.ItemTemplateId; }
        set { ThisAdapter.ItemTemplateId = value; }
    }

    private ICommand _itemClick;
    public new ICommand ItemClick
    {
        get { return _itemClick; }
        set { _itemClick = value; if (_itemClick != null) EnsureItemClickOverloaded(); }
    }

    public ICommand GroupClick { get; set; }

    private bool _itemClickOverloaded = false;
    private void EnsureItemClickOverloaded()
    {
        if (_itemClickOverloaded)
            return;

        _itemClickOverloaded = true;
        base.ChildClick += (sender, args) => ExecuteCommandOnItem(this.ItemClick, args.GroupPosition, args.ChildPosition);
    }


    protected virtual void ExecuteCommandOnItem(ICommand command, int groupPosition, int position)
    {
        if (command == null)
            return;

        var item = ThisAdapter.GetRawItem(groupPosition, position);
        if (item == null)
            return;

        if (!command.CanExecute(item))
            return;

        command.Execute(item);
    }
}

そしてアダプター

public class BindableExpandableListAdapter : MvxAdapter, IExpandableListAdapter
    {
    private IList _itemsSource;

    public BindableExpandableListAdapter(Context context)
        : base(context)
    {
        
    }

    int groupTemplateId;
    public int GroupTemplateId
    {
        get { return groupTemplateId; }
        set
        {
            if (groupTemplateId == value)
                return;
            groupTemplateId = value;

            // since the template has changed then let's force the list to redisplay by firing NotifyDataSetChanged()
            if (ItemsSource != null)
                NotifyDataSetChanged();
        }
    }

    protected override void SetItemsSource(System.Collections.IEnumerable value)
    {
        Mvx.Trace("Setting itemssource");
        if (_itemsSource == value)
            return;
        var existingObservable = _itemsSource as INotifyCollectionChanged;
        if (existingObservable != null)
            existingObservable.CollectionChanged -= OnItemsSourceCollectionChanged;

        _itemsSource = value as IList;

        var newObservable = _itemsSource as INotifyCollectionChanged;
        if (newObservable != null)
            newObservable.CollectionChanged += OnItemsSourceCollectionChanged;

        if (value != null)
        {
            // dit weggehaald FlattenAndSetSource(value);
        }
        else
            base.SetItemsSource(null);
    }



    public int GroupCount { get { return (_itemsSource != null ? _itemsSource.Count : 0); } }
    public void OnGroupExpanded(int groupPosition)
    {
        // do nothing
    }

    public void OnGroupCollapsed(int groupPosition)
    {
        // do nothing
    }

    public bool IsChildSelectable(int groupPosition, int childPosition)
    {
        return true;
    }

    public View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
    {
        var item = _itemsSource[groupPosition];
        return base.GetBindableView(convertView, item, GroupTemplateId);
    }

    public long GetGroupId(int groupPosition)
    {
        return groupPosition;
    }

    public Java.Lang.Object GetGroup(int groupPosition)
    {
        return null;
    }

    public long GetCombinedGroupId(long groupId)
    {
        return groupId;
    }

    public long GetCombinedChildId(long groupId, long childId)
    {
        return childId;
    }

    public object GetRawItem(int groupPosition, int position)
    {
        return ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList()[position];
    }

    public View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
    {
        var sublist = ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList();

        var item = sublist[childPosition];
        return base.GetBindableView(convertView, item, ItemTemplateId);
    }

    public int GetChildrenCount(int groupPosition)
    {
        return ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList().Count();
    }

    public long GetChildId(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    public Java.Lang.Object GetChild(int groupPosition, int childPosition)
    {
        return null;
    }

    //public object GetRawItem
}

XAML コードの例:

<DeapExtensions.Binding.Droid.Views.BindableExpandableListView
    android:minWidth="25px"
    android:minHeight="25px"
    android:id="@+id/toclist"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    local:MvxBind="ItemsSource Chapters; ItemClick ShowCommand"
    local:MvxItemTemplate="@layout/indextocsectionlistitem"
    local:GroupItemTemplate="@layout/indextocitem"
    android:background="@android:color/white" />

そして、さらにいくつかのデータ例 (疑似コード):

public class SubItem {
  public String Name {get; set;}
}

// this is the special part: a chapter does not CONTAIN a sublist, but IS a list of subitems.
public class Chapter : List<Subitem> {
  public String Name {get; set;}
}

// en some usage code
var chapters = new List<Chapter>();
var chapter = new Chapter(){Name = "chap 1"};
chapter.Add(new SubItem(){Name = " 1"});
chapter.Add(new SubItem(){Name = "item 2"});
chapters.Add(chap);

これは私の MvxBindingAttributes.xml です

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="MvxBinding">
    <attr name="MvxBind" format="string"/>
    <attr name="MvxLang" format="string"/>
  </declare-styleable>
  <declare-styleable name="MvxControl">
    <attr name="MvxTemplate" format="string"/>
  </declare-styleable>
  <declare-styleable name="MvxListView">
    <attr name="MvxItemTemplate" format="string"/>
    <attr name="MvxDropDownItemTemplate" format="string"/>
    <attr name="GroupItemTemplate" format="string"/>

  </declare-styleable>
  <item type="id" name="MvxBindingTagUnique"/>
  <declare-styleable name="MvxImageView">
    <attr name="MvxSource" format="string"/>
  </declare-styleable>
</resources>

ところで: MvvmCross に残っているプロジェクトは 1 つだけです。残りは Xamarin.Forms に変換されているか、Xamarin から離れています。したがって、コードはもう更新されません。

于 2013-07-18T21:49:28.930 に答える
1

私の知る限り、誰もこれを行ったことはありません

しかし、既存の Android コントロールをかなり簡単にバインドされたコントロールに変換することができます。@deapsquatter のリポジトリでそれがどのように行われるかを正確に見てきました。

ExpandableListView を変換するには、一度に 1 ステップずつ実行します。

  1. まず、使用したい構造のデータを取得します
  2. 次に、バインドされていない UI を手作りします。ラピッド プロトタイピングのみです。
  3. 最後に、@deapsquatter のサンプルを取り上げて、同じ原則を適用してみてください。

特定の問題が発生した場合は、いつでもここに戻ってそれらの問題について質問できます。しかし、最初に 1 と 2 を用意しておくことで、質問する内容が確実になります。

それが役立つことを願っています。

于 2013-02-21T19:31:30.950 に答える