Xamarin Forms Custom ItemsControl

各位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);
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值