Search code examples
silverlightitemscontrolitemtemplatealternate

Silverlight ItemsControl with Alternating ItemTemplate


Silverlight does not support Alternating Item Templates in an ItemsControl. I have a few ideas in mind as to how to accomplish this, but to avoid polluting the potential answers, I'll leave them out.

The idea is the same as a normal ItemTemplate in that it won't depend on anything in the bound data context to function. I would like the functionality to remain in the View (assuming MVVM)

If you had to design a method of providing alternating templates (and I mean a full data template) for an ItemsControl, how would you accomplish this?


Solution

  • Extend ItemsControl and in the PrepareContainerForItemOverride override you can apply alternating templates.

            protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            if (!object.ReferenceEquals(element, item))
            {
                ContentPresenter presenter = element as ContentPresenter;
                ContentControl control = null;
                if (presenter == null)
                {
                    control = element as ContentControl;
                    if (control == null)
                    {
                        return;
                    }
                }
                DataTemplate itemTemplate = null;
                if ((this.ItemTemplate != null) && (this.DisplayMemberPath != null))
                {
                    throw new InvalidOperationException("Cannot set ItemTemplate and DisplayMemberPath simultaneously");
                }
                if (!(item is UIElement))
                {
                    if (this.ItemTemplate != null)
                    {
                        if(this.AlternateItemTemplate != null && ((alternationIndex % 2)) == 1)
                            itemTemplate = this.AlternateItemTemplate;
                        else
                        itemTemplate = this.ItemTemplate;
                        alternationIndex++;
                    }
                }
                if (presenter != null)
                {
                    if (itemTemplate != null)
                    {
                        presenter.Content = item;
                        presenter.ContentTemplate = itemTemplate;
                    }
                    else
                    {
                        presenter.SetBinding(ContentControl.ContentProperty, new Binding(this.DisplayMemberPath));
                    }
                }
                else
                {
                    control.Content = item;
                    control.ContentTemplate = itemTemplate;
                }
            }
        }
    

    The way I'm using alternationIndex is not very accurate and would need to be changed, but otherwise this should work.