2012-03-14 105 views
2

我想爲每個列與可能值的下拉列表相關的表格製作一個控制模板,並且每一行都有它自己獨特的一組「選定值」。它看起來像這樣:對於每個繼承類類型,繼承的靜態成員是不同的?

<DataTemplate x:Key="ColourCellDataTemplate"> 
    <local:ColourDictionary Key="{TemplateBinding Content}"> 
     <local:ColourDictionary.ContentTemplate> 
      <DataTemplate> 
       <TextBlock Style="{StaticResource EditableTextCell}" Text="{Binding ColourName}" /> 
      </DataTemplate> 
     </local:ColourDictionary.ContentTemplate> 
    </local:ColourDictionary> 
</DataTemplate> 

我有這些類的約10個,每個初始化的不同的數據表和排序鍵,但所有的基本操作和事件是相同的。

這些類中的每個人都有自己的靜態緩存DataView的成員,這是該類的所有實例之間共享:

public class ColourDictionary : DataTableDictionary 
{ 
    private static DataView cachedView; 

    public ColourDictionary(){ } 

    protected override DataView createView() 
    { 
     if (CachedView == null) 
     { 
      CachedView = base.buildView(table:((App)App.Current).ApplicationData.Colours, 
             keyField:"ColorCode"); 
     } 
     return CachedView; 
    } 
} 

正如你可以看到 - 當基類的推移創建使用的數據視圖字典中,它使用了一種虛擬方法,允許不同的繼承類在他們自己的視圖上傳遞 - 但每個類都需要跟蹤他們自己的靜態緩存。

我希望這個緩存是邏輯我可以保留在基類中,這樣「CreateView()」只需要返回一個新的DataView並且只會被調用一次,之後基類將簡單地使用它是每個繼承類類型的自己的緩存。


解決方案

非常感謝你的兩個非常好,非常有效的想法。我希望你們都能得到更多的讚揚。我採用了後一種解決方案,因爲我爲了簡潔而成爲一名吸盤。然後我去一個遠一點,以便實現類只需要重寫虛擬財產的getter滿足要求:

public class CATCodeDictionary : DataTableDictionary<CATCodeDictionary> 
{ 
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.CATCodeList; } } 
    protected override string indexKeyField { get { return "CatCode"; } } 
    public CATCodeDictionary() { } 
} 
public class CCYDictionary : DataTableDictionary<CCYDictionary> 
{ 
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.CCYList; } } 
    protected override string indexKeyField { get { return "CCY"; } } 
    public CCYDictionary() { } 
} 
public class COBDictionary : DataTableDictionary<COBDictionary> 
{ 
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.COBList; } } 
    protected override string indexKeyField { get { return "COB"; } } 
    public COBDictionary() { } 
}  
etc... 

基類

public abstract class DataTableDictionary<T> : where T : DataTableDictionary<T> 
{ 
    private static DataView _IndexedView = null; 

    protected abstract DataTable table { get; } 
    protected abstract string indexKeyField { get; } 

    public DataTableDictionary() 
    { 
     if(_IndexedView == null) 
     { 
      _IndexedView = CreateIndexedView(table.Copy(), indexKeyField); 
     } 
    } 

    private DataView CreateIndexedView(DataTable table, string indexKey) 
    { // Create a data view sorted by ID (keyField) to quickly find a row. 
     DataView dataView = new DataView(table); 
     dataView.Sort = indexKey; 
     return dataView; 
    } 

回答

2

您可以使用泛型:

public class DataTableDictionary<T> where T: DataTableDictionary<T> 
{ 
    private static DataView cachedView; 
} 

public class ColourDictionary : DataTableDictionary<ColourDictionary> 
{ 
} 

public class XyDictionary : DataTableDictionary<XyDictionary> 
{ 
} 

這裏每個類都有自己的靜態成員。

+0

兩個很棒的解決方案。我喜歡這個,因爲它很簡潔。 – Alain 2012-03-14 14:15:30

+0

@Alain - 感謝您的編輯。 – Henrik 2012-03-15 07:27:19

1

您可以在基本使用字典高速緩存類是這樣的:

public class DataTableDictionary 
{ 
    private static Dictionary<Type, DataView> cachedViews = new Dictionary<Type, DataView>(); 

    protected abstract DataView CreateView(); 

    public DataView GetView() 
    { 
     DataView result; 
     if (!cachedViews.TryGetValue(this.GetType(), out result)) 
     { 
      result = this.CreateView(); 
      cachedViews[this.GetType()] = result; 
     } 
     return result; 
    } 
} 

public class ColourDictionary : DataTableDictionary 
{ 

    protected override DataView CreateView() 
    { 
     return base.buildView(table: ((App)App.Current).ApplicationData.Colours, keyField: "ColorCode");   
    } 
} 

或者你應該使用ConcurentDictionary,如果你需要線程安全

+0

兩個很棒的解決方案。爲了清晰起見,我喜歡這個。 – Alain 2012-03-14 14:15:44