各位xamarin 的朋友们,有没有遇到 listView Control展示数据有空白在底部,特别是ScrollView 里面的Listview
在此向大家提供一个自定义的ItemsControl, 支持ItemTemplate、ItemTemplateSelector、ItemsSource绑定、没数据显示No data. 有数据不显示这个文本提示。
public class ItemsControl : StackLayout
{
#region Bindable Property
public static readonly BindableProperty NoTipsHorizontalOptionsProperty =
BindableProperty.Create("NoTipsHorizontalOptions", typeof(LayoutOptions), typeof(ItemsControl), LayoutOptions.Center, propertyChanging: OnNoTipsHorizontalPropertyChanged);
public LayoutOptions NoTipsHorizontalOptions
{
get { return (LayoutOptions)GetValue(NoTipsHorizontalOptionsProperty); }
set { SetValue(NoTipsHorizontalOptionsProperty, value); }
}
static void OnNoTipsHorizontalPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
var layoutOption =(LayoutOptions)newValue ;
uc.TipsLabel.HorizontalOptions = layoutOption;
}
public static readonly BindableProperty ItemTemplateSelectorProperty =
BindableProperty.Create("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(ItemsControl), null, propertyChanging: OnItemTemplateSelectorPropertyChanged);
public DataTemplateSelector ItemTemplateSelector
{
get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
set { SetValue(ItemTemplateSelectorProperty, value); }
}
static void OnItemTemplateSelectorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
var template = newValue as DataTemplateSelector;
uc.ItemTemplateSelector = template;
BindableLayout.SetItemTemplateSelector(uc.ContentLayout, uc.ItemTemplateSelector);
}
public static readonly BindableProperty ItemTemplateProperty =
BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(ItemsControl), null, propertyChanging: OnItemTemplatePropertyChanged);
/// <summary>
/// This DataTemplate Do not use ViewCell !!!
/// </summary>
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
static void OnItemTemplatePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
var template = newValue as DataTemplate;
uc.ItemTemplate = template;
BindableLayout.SetItemTemplate(uc.ContentLayout, template);
}
public static readonly BindableProperty NoDataTipsTextProperty =
BindableProperty.Create("NoDataTipsText", typeof(string), typeof(ItemsControl), "No data.", propertyChanging: OnNoDataTipsTextChanged);
/// <summary>
/// diplay Text when no data records.
/// </summary>
public string NoDataTipsText
{
get { return (string)GetValue(NoDataTipsTextProperty); }
set { SetValue(NoDataTipsTextProperty, value); }
}
static void OnNoDataTipsTextChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
uc.NoDataTipsText = newValue.ToString();
uc.TipsLabel.Text = newValue.ToString();
}
public static readonly BindableProperty TipsMarginProperty =
BindableProperty.Create("TipsMargin", typeof(Thickness), typeof(ItemsControl), new Thickness(0, 10, 0, 0), propertyChanging: OnTipsMarginChanged);
/// <summary>
/// Tips margin
/// </summary>
public Thickness TipsMargin
{
get { return (Thickness)GetValue(TipsMarginProperty); }
set { SetValue(TipsMarginProperty, value); }
}
static void OnTipsMarginChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
Thickness margin = (Thickness)newValue;
uc.TipsMargin = margin;
uc.TipsLabel.Margin = margin;
}
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create("ItemsSource", typeof(IEnumerable<object>), typeof(ItemsControl), null, propertyChanged: OnItemsSourceChanged);
public IEnumerable<object> ItemsSource
{
get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var uc = bindable as ItemsControl;
var source = newValue as IEnumerable<object>;
uc.ItemsSource = source;
BindableLayout.SetItemsSource(uc.ContentLayout, source);
if (source == null || source.Count() == 0)
{
uc.TipsLabel.IsVisible = true;
}
else
{
uc.TipsLabel.IsVisible = false;
}
if (null != source)
{
if (source is INotifyCollectionChanged)
{
((INotifyCollectionChanged)source).CollectionChanged += uc.ItemsControl_CollectionChanged;
}
}
}
protected void ItemsControl_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (ItemsSource == null || ItemsSource.Count() == 0)
{
TipsLabel.IsVisible = true;
}
else
{
TipsLabel.IsVisible = false;
}
}
#endregion Bindable Property
protected StackLayout ContentLayout { set; get; }
protected Label TipsLabel { set; get; }
public ItemsControl()
{
ContentLayout = new StackLayout();
TipsLabel = new Label();
TipsLabel.HorizontalOptions = this.NoTipsHorizontalOptions;
TipsLabel.Text = this.NoDataTipsText;
this.Children.Add(TipsLabel);
this.Children.Add(ContentLayout);
}
}