Визуализация гетерогенной коллекции моделей представлений в Silverlight 2 - PullRequest
1 голос
/ 14 июля 2009

У меня есть иерархия моделей представлений, представляющих форматированный контент:

public abstract class ContentPartViewModel : ViewModel
{
}

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

public class TitleContentPartViewModel : TextContentPartViewModel
{
}

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

У меня есть модель всеобъемлющего представления, которая содержит коллекцию ContentPartViewModel s для визуализации:

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, который затем использует конвертер для отключения всего пользовательского интерфейса, кроме части, относящейся к этой части контента:

<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

1 Ответ

1 голос
/ 15 июля 2009
  1. Да. Тип данных в 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);
    }
}
...