未定义类型的集合

时间:2013-05-30 09:38:49

标签: c# wpf

我正在尝试使用表名创建一个可以从我的数据库中检索表的函数。 我已经使用DataTable工作,但我更喜欢使用ObservableCollection / List,因为我可以在ListCollectionView中使用它来在WPF中的DataGrid中使用它的分组可能性。

但是我现在面临的问题是我在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

2 个答案:

答案 0 :(得分:4)

有两种选择:

  • 返回非通用IList类型而不是ObservableCollection<>。我希望绑定仍然可以解决实际类型为ObservableCollection<>并且能够观察到更改。
  • 使方法通用,并完全删除name参数:根据类型参数计算要获取的集合。 (这对我来说有些难看,因为它很可能不是真正的通用 - 你可能会使用一组有限的类型。)

答案 1 :(得分:1)

  

我正在尝试创建一个可以从我的表中检索表的函数   数据库,使用表名。我已经使用DataTable工作了,   但我更喜欢使用ObservableCollection / List,因为我   然后可以在ListCollectionView中使用它来使用它的分组   WPF中DataGrid的可能性。

回答这个我创建了一个样本。看看这个。我正在使用Northwind数据库。这样就可以将客户数据表加载到DataGrid并动态分组。

要使用它,您可以根据数据库中的表名简单地调用表,然后将此表结果作为itemsource传递给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);

        }
    }
}