2010-08-05 77 views
0

這個問題是強連接到這個答案爲「How to reference a generic type in the DataType attribute of a HierarchicalDataTemplate?如何在DataTemplate的DataType屬性中引用泛型類型的特定實現?

我跟着這個問題的答案的基本思路,並創造了這個數據結構:

<!-- for DictItemVM<string, Remote.Address> which is a viewmodel for a KeyValuePair<...> --> 
<x:Array Type="{x:Type sys:Type}" 
     x:Key="KVParamsStringToRemoteAddress" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:remote="clr-namespace:Remote" 
     xmlns:mvvm="clr-namespace:MVVM"> 
    <x:Type TypeName="sys:String" /> 
    <mvvm:GenericType BaseType="{x:Type TypeName=remote:Address}"/> 
</x:Array> 

<mvvm:GenericType xmlns:mvvm="clr-namespace:MVVM" 
        BaseType="{x:Type TypeName=mvvm:DictItemVM`2}" 
        InnerTypes="{StaticResource KVParamsStringToRemoteAddress}" 
        x:Key="DictItemVMOfStringToRemoteAddress"/> 

DictItemVM<T,U>是一個視圖模型爲KeyValuePair<...>和源自BaseVM。 BaseVM有一個DataTemplate視圖,但我努力爲DictItemVM<string, Remote.Address>創建一個。
Remote.Address是一個複雜的值類型(存儲路徑和訪問信息)。 Remote.Address具有自己的DataTemplate視圖。
所以,現在我有靜態資源「DictItemVMOfStringToRemoteAddress」,我想用它來指定一個DataTemplate:

<DataTemplate x:Key="TestKey" DataType="{StaticResource DictItemVMOfStringToRemoteAddress}"> 
    <StackPanel> 
     <Label Content="UniqueName" /> 
     <TextBox Text="{Binding UniqueName}" /> 
     <Label Content="Key"/> 
     <TextBox Text="{Binding Key, Mode=OneWay}" IsEnabled="False" /> 
     <Label Content="Value"/> 
     <ContentControl Content="{Binding Value, Mode=OneWay}" /> 
    </StackPanel> 
</DataTemplate> 

現在這個DataTemplate中應該作爲一個視圖,而是用於BaseVM的觀點正在被顯示。
有人給我這個提示嗎?

[編輯:2010-08-09]
有些事情我想:

在X:數組定義我更換
<mvvm:GenericType BaseType="{x:Type TypeName=remote:Address}"/>

<x:Type TypeName="remote:Address"/>
因爲這是它基本上是- 沒有不同。

也試過在標籤之間建立數據類型(而不是鏈接到一個靜態資源)是這樣的:

<DataTemplate x:Key="TestKey"> 
    <DataTemplate.DataType> 
     <Binding> 
      <Binding.Source> 
       <mvvm:GenericType 
        BaseType="{x:Type TypeName=mvvm:DictItemVM`2}"> 
        <mvvm:GenericType.InnerTypes> 
         <x:Type TypeName="sys:String" /> 
         <x:Type TypeName="remote:Address"/> 
        </mvvm:GenericType.InnerTypes> 
       </mvvm:GenericType> 
      </Binding.Source> 
     </Binding> 
    </DataTemplate.DataType> 

使用和不使用X試了一下:在GenericType.InnerTypes內陣列,都讓我this錯誤。

試圖從一個靜態屬性傳遞的類型是這樣的:
DataType="{x:Static mvvm:StaticTypes.DictItemVMOfStringToRemoteAddress}"
像這樣:
DataType="{Binding Path={x:Static mvvm:StaticTypes.DictItemVMOfStringToRemoteAddress}}"
沒有區別。

奇怪的是,這個特定的DataTemplate需要有一些x:Key值,與xaml資源文件中所有指向常規類型的其他值相比,例如:DataType="{x:Type mvvm:EffectVM}"。如果我刪除了x:Key,則會出現this錯誤。

回答

1

我找到了一個解決方案,但該解決方案並不令人滿意。

在XAML中,營造一個DataTemplate你要顯示的給它一些獨特的X每種類型的KeyValuePair<T,U>:關鍵:

<DataTemplate x:Key="DictItemOfStringAndAddressVM"> 
    <!-- ... --> 
</DataTemplate> 

然後在代碼隱藏,創建一個DataTemplateSelector並覆蓋SelectTemplate:

public class GenericDataTemplateSelector : System.Windows.Controls.DataTemplateSelector 
{ 
    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) 
    { 
     FrameworkElement element = container as FrameworkElement; 

     if ((element != null) && (item != null)) 
     { 
      if (item is DictItemVM<string, Remote.Address>) 
      { 
       return element.FindResource("DictItemOfStringAndAddressVM") as DataTemplate; 
      } 
      else if(item is SomeOtherComplexType) 
      { 
       // ... 
      } 
      else return base.SelectTemplate(item, container); 
     } 
     return null; 
    } 
} 
在XAML

此外,聲明這個類作爲一種資源:

<mvvm:GenericDataTemplateSelector x:Key="GenDataTempSelect"/> 

最後,(對我來說)在ContentControl中,添加屬性:

ContentTemplateSelector="{StaticResource GenDataTempSelect}" 

-

缺點:

  • 當創建你必須在兩個位置更改代碼的新的DataTemplate 。
  • 每個ContentControl,ListView,...都必須設置它的適當屬性。
  • 沒有真正回答如何在WPF中引用泛型類型的問題!

優點:

  • 容易增加新類型的任何結構或複雜的(享受的所有好處C#有超過WPF ...)
  • 在WPF沒有複雜的嵌套類型描述,上述解決方案將需要。
相關問題