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