Элементы управления Silverlight с помощью альтернативного шаблона элемента
Silverlight не поддерживает шаблоны чередующихся элементов в ItemsControl. У меня есть несколько идей о том, как этого добиться, но чтобы не загрязнять потенциальные ответы, я их опущу.
Идея та же, что и у обычного ItemTemplate, в том, что он не будет зависеть ни от чего в связанном контексте данных для функционирования. Я хотел бы, чтобы функциональность оставалась в представлении (при условии MVVM)
Если бы вам пришлось разработать метод предоставления чередующихся шаблонов (а я имею в виду полный шаблон данных) для ItemsControl, как бы вы этого достигли?
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
не очень точный и должен быть изменен, но в противном случае это должно работать.
Я застрял на той же проблеме недавно. В конце концов я решил, что присоединенные свойства - это путь, и в итоге получил функциональность, которая работает примерно так:
<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/
Фил
Ps извините за откровенную саморекламу:)
Я бы поместил свойство Bool в класс ItemModel и написал DataTrigger на ItemTemplate, чтобы придать другой вид. В коллекции мы можем перебрать и установить это Bool соответственно