定制Xamarin.Forms.ListView中的问题
任务:我需要实现一个控件,以便在android上在GridView中显示项目。
问题的实质并尝试实现它:我创建了从GridListBox Xamarin.Forms.ListView继承的GridListBox类。接下来我创建的GridListBoxRenderer以Xamarin.Forms.Platform.Android.ListViewRenderer为例
我的GridListBox:
public class GridListBox : ListView
{
public static readonly BindableProperty ColumnCountProperty = BindableProperty.Create<GridListBox, int>(r => r.ColumnCount, 2);
public int ColumnCount
{
get { return (int)GetValue(ColumnCountProperty); }
set { SetValue(ColumnCountProperty, value); }
}
public static readonly BindableProperty HorizontalSpacingProperty = BindableProperty.Create<GridListBox, int>(r => r.HorizontalSpacing, 5);
public int HorizontalSpacing
{
get { return (int)GetValue(HorizontalSpacingProperty); }
set { SetValue(HorizontalSpacingProperty, value); }
}
public static readonly BindableProperty VerticalSpacingProperty = BindableProperty.Create<GridListBox, int>(r => r.VerticalSpacing, 5);
public int VerticalSpacing
{
get { return (int)GetValue(VerticalSpacingProperty); }
set { SetValue(VerticalSpacingProperty, value); }
}
}
GridListBox的渲染器:
public class GridListBoxRenderer:NativeRenderer
{
private Cell cellFocused;
protected override void OnModelChanged(VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged(oldModel, newModel);
var realListView = (GridView)Control;
if (realListView == null)
{
realListView = new GridView(Context);
SetNativeControl((View)realListView);
}
cellFocused = (Cell)null;
realListView.Focusable = false;
realListView.DescendantFocusability = DescendantFocusability.AfterDescendants;
realListView.OnFocusChangeListener = (IOnFocusChangeListener)this;
realListView.SetNumColumns(((Controls.GridListBox) newModel).ColumnCount);
realListView.SetHorizontalSpacing(((Controls.GridListBox)newModel).HorizontalSpacing);
realListView.SetVerticalSpacing(((Controls.GridListBox)newModel).VerticalSpacing);
realListView.Adapter = new GridViewAdapter(Context, realListView, (Controls.GridListBox)newModel);
}
public override Size MinimumSize()
{
return new Size(40.0, 40.0);
}
}
然后,有趣的事情开始了:如果以Xamarin.Forms.Platform.Android.ListViewAdapter为例(通过内部访问),则实现GridViewAdapter很容易。要使用ItemTemplate实现公共BaseAdapter.GetView(int位置,View convertView,ViewGroup父级),需要访问Xamarin.Forms.ListView.TemplatedItems,但它是Internal ...
PS Xamarin的开发人员如何计划使开发人员能够自定义Xamarin.Forms(如果大多数属性都具有内部访问权限……)?
PPS定制Xamarin.Forms.Page也有类似的困难。该Xamarin.Forms.Page.InternalChildren属性是内部
解决此问题的方法是使用反射来访问内部化属性
public GridViewAdapter(Context context, GridView realListView, GridListBox gridListView)
{
_context = context;
_realListView = realListView;
_gridListView = gridListView;
var info = _gridListView.GetType().GetProperty("TemplatedItems", BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
var item = info.GetValue(_gridListView);
_templatedItemsList = item as IList;
_templatedItemsINCC = item as INotifyCollectionChanged;
_templatedItemsINCC.CollectionChanged += _templatedItemsINCC_CollectionChanged;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句