123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- using System.Collections;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Markup;
- using HandyControl.Data;
- namespace HandyControl.Controls;
- /// <summary>
- /// ItemsControl的轻量级版本
- /// </summary>
- [DefaultProperty("Items")]
- [ContentProperty("Items")]
- [TemplatePart(Name = ElementPanel, Type = typeof(Panel))]
- public class SimpleItemsControl : Control
- {
- private const string ElementPanel = "PART_Panel";
- public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(
- nameof(ItemTemplate), typeof(DataTemplate), typeof(SimpleItemsControl),
- new FrameworkPropertyMetadata(default(DataTemplate), OnItemTemplateChanged));
- public static readonly DependencyProperty ItemContainerStyleProperty = DependencyProperty.Register(
- nameof(ItemContainerStyle), typeof(Style), typeof(SimpleItemsControl),
- new PropertyMetadata(default(Style), OnItemContainerStyleChanged));
- public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
- nameof(ItemsSource), typeof(IEnumerable), typeof(SimpleItemsControl),
- new PropertyMetadata(default(IEnumerable), OnItemsSourceChanged));
- public SimpleItemsControl()
- {
- var items = new ObservableCollection<object>();
- items.CollectionChanged += (s, e) =>
- {
- if (e.NewItems != null && e.NewItems.Count > 0)
- {
- SetValue(HasItemsPropertyKey, ValueBoxes.TrueBox);
- }
- OnItemsChanged(s, e);
- };
- Items = items;
- }
- public IEnumerable ItemsSource
- {
- get => (IEnumerable) GetValue(ItemsSourceProperty);
- set => SetValue(ItemsSourceProperty, value);
- }
- [Bindable(true)]
- [Category("Content")]
- public Style ItemContainerStyle
- {
- get => (Style) GetValue(ItemContainerStyleProperty);
- set => SetValue(ItemContainerStyleProperty, value);
- }
- [Bindable(true)]
- public DataTemplate ItemTemplate
- {
- get => (DataTemplate) GetValue(ItemTemplateProperty);
- set => SetValue(ItemTemplateProperty, value);
- }
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
- [Bindable(true)]
- public Collection<object> Items { get; }
- internal Panel ItemsHost { get; set; }
- private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ((SimpleItemsControl) d).OnItemsSourceChanged((IEnumerable) e.OldValue, (IEnumerable) e.NewValue);
- }
- protected virtual void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
- {
- }
- public override void OnApplyTemplate()
- {
- ItemsHost?.Children.Clear();
- base.OnApplyTemplate();
- ItemsHost = GetTemplateChild(ElementPanel) as Panel;
- Refresh();
- }
- protected virtual void OnItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- Refresh();
- UpdateItems();
- }
- protected virtual DependencyObject GetContainerForItemOverride() => new ContentPresenter();
- protected virtual bool IsItemItsOwnContainerOverride(object item) => item is ContentPresenter;
- protected virtual void PrepareContainerForItemOverride(DependencyObject element, object item)
- {
- switch (element)
- {
- case ContentControl contentControl:
- contentControl.Content = item;
- contentControl.ContentTemplate = ItemTemplate;
- break;
- case ContentPresenter contentPresenter:
- contentPresenter.Content = item;
- contentPresenter.ContentTemplate = ItemTemplate;
- break;
- }
- }
- private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- => (d as SimpleItemsControl)?.OnItemTemplateChanged(e);
- protected virtual void OnItemTemplateChanged(DependencyPropertyChangedEventArgs e) => Refresh();
- private static void OnItemContainerStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- => (d as SimpleItemsControl)?.OnItemContainerStyleChanged(e);
- protected virtual void OnItemContainerStyleChanged(DependencyPropertyChangedEventArgs e) => Refresh();
- internal static readonly DependencyPropertyKey HasItemsPropertyKey =
- DependencyProperty.RegisterReadOnly(nameof(HasItems), typeof(bool), typeof(SimpleItemsControl),
- new PropertyMetadata(ValueBoxes.FalseBox));
- public static readonly DependencyProperty HasItemsProperty = HasItemsPropertyKey.DependencyProperty;
- public bool HasItems => (bool) GetValue(HasItemsProperty);
- protected virtual void Refresh()
- {
- if (ItemsHost == null) return;
- ItemsHost.Children.Clear();
- foreach (var item in Items)
- {
- DependencyObject container;
- if (IsItemItsOwnContainerOverride(item))
- {
- container = item as DependencyObject;
- }
- else
- {
- container = GetContainerForItemOverride();
- PrepareContainerForItemOverride(container, item);
- }
- if (container is FrameworkElement element)
- {
- element.Style = ItemContainerStyle;
- ItemsHost.Children.Add(element);
- }
- }
- }
- protected virtual void UpdateItems()
- {
- }
- }
|