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不支持DataTemplate类中的DataType属性,因此这不是一个选项。

另一种选择是提供一个DataTemplateSelector并进行自己的视图模型类型到DataTemplate的映射。唉,SL2中的ItemsControl没有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的情况是否有所改善?

感谢, 肯特

+0

,如果它让你感觉更好,在模型视图“查看”实际上解释了可视性的东西,在你的绑定的存在。但是我确实感到你的痛苦(也等SL5) – Vlagged 2009-07-14 13:18:49

回答

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); 
    } 
} 
+0

谢谢迈克尔。不理想的是我必须自己创建所有的基础设施和子类,但是看起来它应该可以工作。一旦我尝试过,会更新。 – 2009-07-15 10:46:00