2012-03-14 3 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 из этих классов, каждый инициализируется с другим DataTable и ключ сортировки, но все основные операции и события одинаковы.

Каждый из этих классов имеет свой собственный статический кэшированный элемент 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; 
    } 
} 

Как вы можете видеть - когда базовый класс идет создать DataView для использования в словаре он использует виртуальный метод, который позволяет различным наследующим классам передавать свой собственный вид, но каждый класс должен отслеживать свой собственный статический кеш.

Я надеялся, что это кеширование было логическим, я мог бы сохранить в базовом классе, так что «CreateView()» должен был бы только вернуть новый DataView и будет только когда-либо вызываться один раз, после чего базовый класс просто использовал бы это собственный кэш для каждого типа наследуемого класса.


Решение

Спасибо большое за два очень хороших и очень уважительным идей. Надеюсь, вы оба получите больше очков. Я пошел с последним решением, потому что для хватки я - присоска. Затем я пошел немного дальше, так что классы реализации нужно только переопределить геттер виртуальной собственности для удовлетворения требований:

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

+0

@Alain - спасибо за редактирование. – Henrik

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

Смежные вопросы