1

У меня есть иерархия моделей зрения, представляющие отформатированное содержание:Визуализация разнородного просмотра моделей в Silverlight 2

public abstract class ContentPartViewModel : ViewModel 
{ 
} 

public class TextContentPartViewModel : ContentPartViewModel 
{ 
    public string Text { ... } 
} 

public class TitleContentPartViewModel : TextContentPartViewModel 
{ 
} 

public class HyperlinkContentPartViewModel : TextContentPartViewModel 
{ 
    public string Uri { ... } 
} 

Я всеохватывающий вид модель, которая содержит коллекцию ContentPartViewModel с быть вынесен:

public class ContentViewModel 
{ 
    public ICollection<ContentPartViewModel> ContentParts { ... } 
} 

Я тогда ContentView, который визуализирует все части содержания:

<UserControl ...> 
    <ItemsControl ItemsSource="{Binding ContentParts}"/> 
</UserControl> 

В идеальном мире я бы просто определил DataTemplate для каждого из типов содержимого контента, и они будут отображены соответствующим образом. Однако Silverlight не поддерживает свойство DataType на классе DataTemplate, так что это не вариант.

Другой вариант - предоставить DataTemplateSelector и сделать сопоставление с модели типа просмотра до DataTemplate. Увы, ItemsControl в SL2 не имеет ItemTemplateSelector Недвижимость - только ItemTemplate Недвижимость.

Это оставило меня без выбора, кроме как обеспечить ItemTemplate, который затем использует конвертер, чтобы отключить все UI отдельно от части, относящейся к этой содержательной части:

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <Grid> 
      <TextBlock Text="{Binding Text}" FontWeight="Bold" Visibility="{Binding Converter={StaticResource TitleContentPartConverter}}"/> 

      <TextBlock Text="{Binding Text}" Visibility="{Binding Converter={StaticResource TextContentPartConverter}}"/> 

      <HyperlinkButton Content="{Binding Text}" NavigateUri="{Binding Uri}" Visibility="{Binding Converter={StaticResource HyperlinkContentPartConverter}}"/> 
     </Grid> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 

Это, очевидно, довольно ужасно, как для производительности и удобочитаемости/правильности кода. Это также значительно усложняет форматирование вывода. Итак, вопросы:

  1. Может ли кто-нибудь порекомендовать лучший способ сделать это в SL2?
  2. Может ли кто-нибудь подтвердить, улучшилась ли ситуация в SL3?

Спасибо, Kent

+0

, если это заставляет Вас чувствовать себя лучше, «View» в видовом фактически объясняет наличие видимости вещей в ваших креплениях. Я все же чувствую вашу боль (и жду SL5 тоже) – Vlagged

ответ

1
  1. Да. DataType в DataTemplate не поддерживается в Silverlight 2 или Silverlight 3.

  2. Вы можете работать с ItemTemplateSelector в Silverlight. Пожалуйста, взгляните на этот образец.

http://silverlight.net/forums/t/12598.aspx

protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 
{ 
    base.PrepareContainerForItemOverride(element, item); 
    DataTemplateSelector selector = this.ItemTemplateSelector; 

    if (null != selector) 
    { 
     ((ContentPresenter)element).ContentTemplate = selector.SelectTemplate(item, element); 
    } 
} 
+0

Спасибо Майкл. Не идеально, что я должен сам создать всю эту инфраструктуру и подкласс различных ItemsControls, но похоже, что она должна работать. Будет обновляться, как только я это пробовал. –

+0

Образец и этот вопрос на самом деле не закончен без этой ссылки: http://forums.silverlight.net/forums/t/79266.aspx Это показывает вам, как определить ресурсы DataTemplate и программно ссылаться на них. – xanadont