views:

323

answers:

2

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?

A: 

I would put a Bool property in the Item ViewModel class and write DataTrigger on the ItemTemplate to give a different look. In the collection we can loop through and set that bool appropriately

Jobi Joy
Hi JobiThanks for this, I updated the question to be clearer. I don't want this solution to depend on the VM to function.
Ray Booysen
The ViewModel should never determine how the data is presented
Rick Kierner
+2  A: 

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.

Stephan
Perfect, this is the one I was going to do. Works a charm.
Ray Booysen