-4

好的。经过几个小时的思考,我决定再次问我的问题,因为即使我从上一个问题的答案中得到了一些指导,我也无法让它发挥作用。这是我原来的问题

现在我正在创建一个销售点系统,我希望根据产品类型在我的数据库中将产品动态显示为 TabControl - TabPages 上的按钮。但问题是,我可以将这些产品作为按钮添加到 TabPags,但我无法根据 ProductType 将它们分类到每个 TabPage,因为每个 TabPage 上显示的产品列表相同,如下所示。

在此处输入图像描述

这是我的数据库。

在此处输入图像描述

private void CreateTabPages() // Create Tab Pages for each ProductType
        {
            con.Open();
            SqlDataAdapter sda = new SqlDataAdapter("SELECT DISTINCT ProductType, Description FROM TblProductType", con);
            DataTable dt = new DataTable();
            sda.Fill(dt);

            foreach (DataRow dr in dt.Rows)
            {
                tabControl1.TabPages.Add(dr["ProductType"].ToString(),dr["Description"].ToString());
            }

            con.Close();   
        }


    private void AddProductsToTabbedPanel() // Add Products to Tab Pages
{

    foreach (TabPage tp in tabControl1.TabPages)
    {
        con.Open();
        SqlDataAdapter sda = new SqlDataAdapter("SELECT DISTINCT Description FROM TblProduct", con);
        DataTable dt = new DataTable();
        sda.Fill(dt);

        FlowLayoutPanel flp = new FlowLayoutPanel();
        flp.Dock = DockStyle.Fill;

        foreach (DataRow dr in dt.Rows)
        {
            Button b = new Button();
            b.Size = new Size(100, 100);
            b.Text = dr["Description"].ToString(); 
            flp.Controls.Add(b);
        }

        tp.Controls.Add(flp);
        con.Close();
    }


}

我非常感谢您对此提供的任何反馈。

4

1 回答 1

1

免责声明:是的,我知道 OP 的图片显示 WinForms,但在另一个问题中,OP 表示他们正在关注YouTube. 我想我会提供另一种方式,他可以使用 WPF 表示相同的数据。

您可以使用 aModel来显示您的每一个DataTypes,而不是处理Raw Data; 看看Object-Relational Mapping,比如 Entity-Framework、NHibernate 等。

创建一个Product模型来保存Product表中的数据。

public class Product {
    public int ProductID {get;set;}
    public int ProductType { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
    public byte[] Image { get; set; }
}

创建一个Product Type模型来保存Product Type表中的数据。

public class ProductType {
    public int ProductTypeID { get; set; }
    public string Description { get; set; }
}

创建一个Window/UserControl来保存你的TabControl.

<Window.Resources>
    <local:ProductConverter x:Key="ProductConverter" />
    <local:ProductTypeConverter x:Key="ProductTypeConverter" />
</Window.Resources>
<TabControl ItemsSource="{Binding MyProducts, 
            Converter={StaticResource ProductConverter}}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding Converter="{StaticResource ProductTypeConverter}">
                            <Binding Path="ProductType"/>
                            <Binding Path="DataContext.MyProductTypes" 
                                     RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ListBox ItemsSource="{Binding}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Button Width="150" Content="{Binding Description}"/>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

使用ItemTemplateandContentTemplate将确保您的所有Product对象都具有相同的格式和样式。

这是根据值将您的整个列表转换Products为组的转换器。ProductsProduct Type

public class ProductConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if(value as List<Product> != null) {
            return (value as List<Product>).GroupBy(a => new { a.ProductType });
        }

        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return null;
    }
}

这是转换器,而不是将Product.ProductType值转换为ProductType.Description

public class ProductTypeConverter : IMultiValueConverter {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if(values[0] != null && values[0] != DependencyProperty.UnsetValue &&
            values[1] != null && values[1] != DependencyProperty.UnsetValue) {
            string f= (values[1] as List<ProductType>)
                      .Where(a => a.ProductTypeID.Equals(values[0]))
                      .First().Description;
            return f;
        }

        return false;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        return null;
    }
}

创建用于显示TabControl.Items.

public List<Product> MyProducts { get; set; }
public List<ProductType> MyProductTypes { get; set; }

之后,您所要做的就是Raw Data以模型格式表示您的。(我的 SQL 有点不确定)

    SqlCommand sqlCmdProducts = new SqlCommand("SELECT * FROM TblProduct", myConnection);
SqlDataReader productReader = sqlCmdProducts.ExecuteReader();
while (productReader.Read()) {
    MyProductTypes.Add(new ProductType() {
    ProductTypeID = Int32.Parse(productReader["ProductType"].ToString()),
    Description = Int32.Parse(productReader["Description"].ToString()),
    };
}

SqlCommand sqlCmdProductType = new SqlCommand("SELECT * FROM TblProductType", myConnection);
SqlDataReader productTypeReader = sqlCmdProductType.ExecuteReader();
while (productTypeReader.Read()) {
    MyProducts.Add(new Product() {
    ProductID = Int32.Parse(productTypeReader["ProductID"].ToString()),
    ProductType = Int32.Parse(productTypeReader["ProductType"].ToString()),
    Description = productTypeReader["Description"].ToString()),
    Price = double.Parse(productTypeReader["Price"].ToString()),
    };
}
于 2013-08-15T18:14:35.553 回答