开发者

Silverlight ItemsControl with Alternating ItemTemplate

Silv开发者_如何学Cerlight 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?


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.


I got stuck on the same problem recently. I eventually decided that attached properties are the way to go, and ended up with functionality that works somewhat like this:

<Grid x:Name="LayoutRoot" Background="White">
    <ListBox x:Name="ListItems">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border>
                    <Border.Style>
                        <Style TargetType="Border">
                            <Setter Property="Background" Value="White" />
                        </Style>
                    </Border.Style>
                    <local:ItemsControlAlternation.AlternateStyle>
                        <Style TargetType="Border">
                            <Setter Property="Background" Value="LightBlue" />
                        </Style>
                    </local:ItemsControlAlternation.AlternateStyle>
                    <ContentPresenter Content="{Binding}" />
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

I posted about it here: http://www.philsversion.com/2010/11/22/alternating-row-styles-in-silverlight/

Phil

P.s. Sorry for the blatant self promotion :)


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜