Reference Sorceを読む。 ItemsControl - 1Page 

Panelを読む解くうえで確認が必要なコントロールの1つである ItemsControl を読んでいきます。

    /// <summary>
    ///     The base class for all controls that have multiple children.
    /// </summary>
    /// <remarks>
    ///     ItemsControl adds Items, ItemTemplate, and Part features to a Control.
    /// </remarks>
    // 
    [DefaultEvent("OnItemsChanged"), DefaultProperty("Items")]
    [ContentProperty("Items")]
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(FrameworkElement))]
    [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)] // cannot be read & localized as string
    public class ItemsControl : Control, IAddChild, IGeneratorHost, IContainItemStorage

デフォルトイベント、デフォルトのプロパティを設定しています。 ItemsControlだと見覚えはある方も多いと思います。 ContentPropertyもItemsですね。 スタイルのプロパティはItemContainerStyleを設定しています。

次にコンストラクタ

        public ItemsControl() : base()
        {
            ShouldCoerceCacheSizeField.SetValue(this, true);
            this.CoerceValue(VirtualizingPanel.CacheLengthUnitProperty);
        }
 
        static ItemsControl()
        {
            // 
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ItemsControl), new FrameworkPropertyMetadata(typeof(ItemsControl)));
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(ItemsControl));
            EventManager.RegisterClassHandler(typeof(ItemsControl), Keyboard.GotKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnGotFocus));
            VirtualizingStackPanel.ScrollUnitProperty.OverrideMetadata(typeof(ItemsControl), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnScrollingModeChanged), new CoerceValueCallback(CoerceScrollingMode)));
            VirtualizingPanel.CacheLengthProperty.OverrideMetadata(typeof(ItemsControl), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCacheSizeChanged)));
            VirtualizingPanel.CacheLengthUnitProperty.OverrideMetadata(typeof(ItemsControl), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCacheSizeChanged), new CoerceValueCallback(CoerceVirtualizationCacheLengthUnit)));
        }

キャッシュや仮想化の文字が目立ちますね。 他には基本的なフォーカス取得時のイベントなどを登録しています。 仮想化周りは面白いですが概要でも要素としてあがっている ” Items”プパティから処理を追っていきます。

       private ItemCollection _items;  

        /// <summary>
        ///     Items is the collection of data that is used to generate the content
        ///     of this control.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Bindable(true), CustomCategory("Content")]
        public ItemCollection Items
        {
            get
            {
                if (_items == null)
                {
                    CreateItemCollectionAndGenerator();
                }
 
                return _items;
            }
        }

        private void CreateItemCollectionAndGenerator()
        {
            _items = new ItemCollection(this);
 
            // ItemInfos must get adjusted before the generator's change handler is called,
            // so that any new ItemInfos arising from the generator don't get adjusted by mistake
            // (see Win8 690623).
            ((INotifyCollectionChanged)_items).CollectionChanged += new NotifyCollectionChangedEventHandler(OnItemCollectionChanged1);
 
            // the generator must attach its collection change handler before
            // the control itself, so that the generator is up-to-date by the
            // time the control tries to use it (bug 892806 et al.)
            _itemContainerGenerator = new ItemContainerGenerator(this);
 
            _itemContainerGenerator.ChangeAlternationCount();
 
            ((INotifyCollectionChanged)_items).CollectionChanged += new NotifyCollectionChangedEventHandler(OnItemCollectionChanged2);
 
            if (IsInitPending)
            {
                _items.BeginInit();
            }
            else if (IsInitialized)
            {
                _items.BeginInit();
                _items.EndInit();
            }
 
            ((INotifyCollectionChanged)_groupStyle).CollectionChanged += new NotifyCollectionChangedEventHandler(OnGroupStyleChanged);
        }