1

フォーマットされたコンテンツを表すビューモデルの階層があります。

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、コンバーターを使用して、そのコンテンツ部分に関連する部分を除くすべての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で状況が改善したかどうかを誰かが確認できますか?

ありがとう、ケント

4

1 に答える 1

1
  1. はい。DataTemplate の DataType は、Silverlight 2 または Silverlight 3 ではサポートされていません。

  2. Silverlight で ItemTemplateSelector を回避できます。こちらのサンプルをご覧ください。

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);
    }
}
于 2009-07-15T02:37:13.500 に答える