2013-05-30 3 views
0

Я пытаюсь сделать функцию, которая может извлекать таблицы из моей базы данных, используя имя таблицы. У меня это работает с использованием DataTable, но я бы предпочел использовать ObservableCollection/List, потому что тогда я могу использовать его в ListCollectionView для использования возможностей группировки в DataGrid в WPF.Коллекция неопределенного типа

Однако я столкнулся с проблемой, что функция, которую я создал в моем классе DataManager, должна возвращать коллекции типов diffirent, соответствующих таблице. Как я могу определить ObservableCollection/List, где тип определен при его создании?

Пример функции (это не работает, но может объяснить, что я пытаюсь сделать):

... 
    public ObservableCollection<object> GetTable(string name) 
    { 
     ObservableCollection<object> table = null; 

     switch (name) 
     { 
      case "PriceList": 
       table = new ObservableCollection<PriceItem>(); 
       //Business logic 
       break; 
      case "CustomerTable": 
       table = new ObservableCollection<Customer>(); 
       //Business logic 
       break; 
     } 

     return table; 
    } 
... 

или, может быть,

... 
    public ObservableCollection<object> GetTable(string name) 
    { 
     ObservableCollection<object> table; 

     switch (name) 
     { 
      case "PriceList": 
       table = getPriceList(); 
       break; 
      case "CustomerTable": 
       table = getCustomers(); 
       break; 
     } 

     return table; 
    } 

    private ObservableCollection<PriceItem> getPriceList() 
    { 
     ObservableCollection<PriceItem> table = null; 

     //Bussiness logic 

     return table; 
    } 
... 

ПРОЕКТ Модифицированный метод (я знаю, что это вероятно, полностью неверно):

public ObservableCollection<T> GetTable<T>() 
    { 
     ObservableCollection<T> table = new ObservableCollection<T>(); 

     switch (typeof(T)) 
     { 
      case "FarrisSeries": 
       table = new ObservableCollection<FarrisSeries>(); 
       //Business logic 
       break; 
      case "FarrisSpecs": 
       table = new ObservableCollection<object>(); 
       //Business logic 
       break; 
     } 

     return table; 
    } 

Возможный прецедент (я, вероятно, сделал все это неправильно, но все же я попробовал: P)

Situation 
--------- 

Window consists of MenuBar and a DataGrid. 
In the menu there is a DropDownButton containing 
a menu which contains a list of all table names. 
Clicking any button will trigger a command that 
will load the table into the DataGrid using the 
MenuItem Header as a parameter. The command will 
then load the appropriate ObservableCollection 
(containing Objects of type related to table name) 
into the DataGrid. 


Case 1: 

- User Clicks "PriceList" 
- function LoadTable("PriceList") is called 
- function retrieves PriceItems from the database 
- function returns ObservableCollection<PriceItem> 
- return is stored in the Object bound to the DataGrid 

Case 2: 

- User Clicks "Customer" 
- function LoadTable("Customers") is called 
- function retrieves Customers from the database 
- function returns ObservableCollection<Customer> 
- return is stored in the Object bound to the DataGrid 
+0

Невозможно. Представьте свой прецедент, чтобы мы могли предложить решение. – Jon

+0

Можете ли вы создать интерфейс (IDisplayable) и позволить различным классам реализовать его?Это будет более приятный стиль OO, а затем просто использование объекта. – Daniel

+0

@ Jon: Извините, но у меня нет прецедента, только некоторые заметки, которые я сделал на бумаге, но ни один из них не связан с этим, мои знания о них все еще слишком ограничены, чтобы реально использовать их. – Kryptoxx

ответ

4

два варианта весной на ум:

  • Верните необщего IList типа вместо ObservableCollection<>. Я надеюсь, что привязка еще будет работать, что действительный тип: ObservableCollection<> и сможете наблюдать за изменениями.
  • Сделать метод общим и полностью избавиться от параметра name: выработать коллекцию для извлечения на основе аргумента типа. (Это чувствует себя немного неуклюжим для меня, так как это не было бы по-настоящему универсальным, по всей вероятности, - вы бы иметь ограниченный набор типов вы могли бы использовать.)
+0

Итак, мне удалось создать общий метод (я никогда не был в этой части программирования OO), но я не понимаю, что вы имеете в виду с аргументом типа. Я попробовал typeof (T), но это, похоже, не работает (добавлен код выше). Однако этот новый материал заставил меня увидеть новые возможности, поэтому я буду продолжать пытаться и публиковать здесь, если буду добиваться большего прогресса. Большое спасибо за быстрый ответ! :) – Kryptoxx

+0

@TomVandenbussche Почему бы просто не пойти на первый вариант. Просто измените тип возвращаемого метода на 'IList' или' ICollection', и все готово. – Clemens

+0

О, вау, я действительно не понимал, что вы имели в виду под неосновным IList (и VS не дал мне много информации), но теперь я узнал, что это такое, я отлично работаю! Большое спасибо!! – Kryptoxx

1

Я пытаюсь сделать функцию, которая может извлекать таблицы из моей базы данных , используя имя таблицы. У меня это работает с использованием DataTable, , но я бы предпочел использовать ObservableCollection/List, потому что I может затем использовать его в ListCollectionView для использования его группировки возможностей в DataGrid в WPF.

Чтобы ответить на этот вопрос, я создал образец. проверьте это. Я использую для этого Northwind db. это обеспечивает постоянную загрузку данных в DataGrid и группировку данных на лету.

Чтобы использовать это, вы можете просто вызвать таблицы на основе имени таблицы из базы данных, а затем передать результат этой таблицы в Datagrid в качестве источника данных, чтобы получить группировку на нем, создали текстовое поле, в котором вы указываете имя группировки , по утраченному фокусу группировка отражается на Datagrid. попробуйте это, и если у вас есть какие-либо вопросы, дайте мне знать.

<Window x:Class="TempTest.DataTableTest" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="DataTableTest" 
     Width="548" 
     Height="292"> 
    <Window.Resources> 
     <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type GroupItem}"> 
         <Expander x:Name="exp" 
            Background="White" 
            Foreground="Black" 
            IsExpanded="True"> 
          <Expander.Header> 
           <TextBlock Text="{Binding Job Title}" /> 
          </Expander.Header> 
          <ItemsPresenter /> 
         </Expander> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="50" /> 
      <RowDefinition Height="210*" /> 
     </Grid.RowDefinitions> 
     <DataGrid Name="dataGrid1" 
        Grid.Row="1" 
        AutoGenerateColumns="true"> 
      <DataGrid.GroupStyle> 
       <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"> 
        <GroupStyle.Panel> 
         <ItemsPanelTemplate> 
          <DataGridRowsPresenter /> 
         </ItemsPanelTemplate> 
        </GroupStyle.Panel> 
       </GroupStyle> 
      </DataGrid.GroupStyle> 
     </DataGrid> 
     <Button Name="button1" 
       Width="56" 
       Height="25" 
       Margin="458,9,0,0" 
       HorizontalAlignment="Left" 
       VerticalAlignment="Top" 
       Click="button1_Click" 
       Content="Button" /> 
     <TextBox Name="textBox1" 
       Width="123" 
       Height="24" 
       Margin="18,10,0,0" 
       HorizontalAlignment="Left" 
       VerticalAlignment="Top" /> 
     <TextBox Name="textBox2" 
       Width="123" 
       Height="24" 
       Margin="147,10,0,0" 
       HorizontalAlignment="Left" 
       VerticalAlignment="Top" /> 
    </Grid> 
</Window> 

Код для этого.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Shapes; 
using System.Data; 
using System.ComponentModel; 

namespace TempTest 
{ 
    /// <summary> 
    /// Interaction logic for DataTableTest.xaml 
    /// </summary> 
    public partial class DataTableTest : Window 
    { 
     public DataTableTest() 
     { 
      InitializeComponent(); 
      textBox2.LostFocus += new RoutedEventHandler(textBox2_LostFocus); 
     } 

     void textBox2_LostFocus(object sender, RoutedEventArgs e) 
     { 
      if (!string.IsNullOrWhiteSpace(textBox2.Text)) 
      { 
       var cv = dataGrid1.ItemsSource as CollectionView; 
       if (cv != null) 
       { 
        cv.GroupDescriptions.Clear(); 
        cv.GroupDescriptions.Add(new PropertyGroupDescription(textBox2.Text)); 
       } 

      } 
     } 

     private void button1_Click(object sender, RoutedEventArgs e) 
     { 

      DataTable dt = new DataTable(); 


      if (textBox1.Text.Equals("customers", StringComparison.InvariantCultureIgnoreCase)) 
      { 
       Data.Northwind_2007DataSetTableAdapters.CustomersTableAdapter c = new Data.Northwind_2007DataSetTableAdapters.CustomersTableAdapter(); 
       dt = c.GetData(); 
      } 
      else if (textBox1.Text.Equals("employees", StringComparison.InvariantCultureIgnoreCase)) 
      { 
       Data.Northwind_2007DataSetTableAdapters.EmployeesTableAdapter emp = new Data.Northwind_2007DataSetTableAdapters.EmployeesTableAdapter(); 
       dt = emp.GetData(); 
      } 


      dataGrid1.ItemsSource = (CollectionView)CollectionViewSource.GetDefaultView(dt.DefaultView); 

     } 
    } 
} 
+0

Спасибо за ваш ответ, но так как я работаю в шаблоне MVVM, это не совсем то, что я ищу. – Kryptoxx

+0

вы можете refector код, который будет использоваться в MVVM. – JSJ

+0

Я знаю, но в конце концов, эта история о ObservableCollections и Generic vs Non-Generic ILists, я остаюсь с этими классами вместо DataTable. Ваша помощь очень ценится, хотя! – Kryptoxx

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