Chodzi o to (umieściłem go w kodzie Deepsqauttera). Po tym, jak uporządkowany kod, będę umieścić go gdzieś pod ręką, czy może jest to przydatny dodatek do mvvmcross się ...
Widok:
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);
}
}
i zasilacz
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
}
i Przykład kodu 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" />
A potem jeszcze jakiś przykład dane (pseudo kod):
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);
To mój 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>
BTW: Mam tylko jeden projekt w lewo w MvvmCross, reszta został przekonwertowany na Xamarin.Forms lub nawet z dala od Xamarin. Kod nie jest już aktualizowany.
udało Ci się rozwiązać ten problem? –