0

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

但是我现在面临的问题是我在 DataManager 类中创建的函数应该返回与表对应的不同类型的集合。我如何定义一个 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
4

2 回答 2

4

两个选项浮现在脑海:

  • 返回非泛型IList类型而不是ObservableCollection<>. 我希望绑定仍然可以确定实际类型是ObservableCollection<>并且能够观察到变化。
  • 使方法通用,并完全摆脱 name 参数:根据类型参数计算要获取的集合。(这对我来说有点难看,因为它很可能不是真正的通用 - 你可以使用的类型有限。)
于 2013-05-30T09:42:29.517 回答
1

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

为了回答这个问题,我创建了一个示例。一探究竟。我为此使用 Northwind db。这提供了将客户数据表加载到 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);

        }
    }
}
于 2013-05-30T11:11:04.133 回答