使用交替的ItemTemplate的Silverlight ItemsControl

3
银光不支持在ItemsControl中使用交替项模板。我有一些想法可以实现这一点,但为了避免干扰潜在的答案,我将它们留出来。
这个想法与正常的ItemTemplate相同,它不依赖于绑定数据上下文中的任何内容来运行。我希望这个功能保留在视图中(假设MVVM)。
如果您必须设计一种提供交替模板(我指完整的数据模板)给ItemsControl的方法,您会如何实现?
3个回答

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方式不太准确,需要改变,但除此之外这个应该可以工作。


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/ Phil
附言:对于明显的自我推销,我很抱歉 :)

1
我会在Item ViewModel类中放置一个Bool属性,并在ItemTemplate上编写DataTrigger来给予不同的外观。 在集合中,我们可以循环遍历并适当地设置该布尔值。

嗨,Jobi谢谢你,我更新了问题以使其更清晰。我不希望这个解决方案依赖于虚拟机才能运行。 - Ray Booysen
2
ViewModel 不应决定数据的呈现方式。 - Rick Kierner
1
这有点名不副实,因为虚拟机的整个目的就是确定数据的呈现方式。布尔值表示可见性,枚举表示状态,这种情况经常发生。 - Ray Booysen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接