具有交替ItemTemplate的Silverlight ItemsControl

时间:2010-06-07 16:38:56

标签: silverlight itemscontrol itemtemplate alternate

Silverlight不支持ItemsControl中的交替项模板。关于如何实现这一点,我有一些想法,但为了避免污染潜在的答案,我会把它们排除在外。

这个想法与普通的ItemTemplate相同,因为它不依赖于绑定数据上下文中的任何东西来运行。我希望功能保留在视图中(假设MVVM)

如果您必须为ItemsControl设计一种提供交替模板(我的意思是完整数据模板)的方法,您将如何实现这一目标?

3 个答案:

答案 0 :(得分:3)

扩展ItemsControl并在PrepareContainerForItemOverride覆盖中,您可以应用交替模板。

        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;
            }
        }
    }

我使用alternationIndex的方式不是很准确,需要更改,否则这应该可行。

答案 1 :(得分:3)

我最近遇到了同样的问题。我最终决定附加属性是要走的路,最后得到的功能有点像这样:

<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>

我在这里发布了这个帖子:http://www.philsversion.com/2010/11/22/alternating-row-styles-in-silverlight/

菲尔

P.S。对不起公然的自我推销:)

答案 2 :(得分:1)

我会在Item ViewModel类中放置一个Bool属性,并在ItemTemplate上编写DataTrigger以提供不同的外观。 在集合中,我们可以循环并适当地设置bool