简体   繁体   English

ComboBox 设置值 C#

[英]ComboBox setting a value C#

I have a tough one for today.我今天有一个艰难的。 I am creating an app in Windows Forms using C#, and I am supposed to make an app that shows every order with its status, date and full price.我正在使用 C# 在 Windows 窗体中创建一个应用程序,我应该制作一个应用程序,显示每个订单的状态、日期和全价。 That is all taken care of.这一切都得到了照顾。 The second form is meant to be order details, where I am supposed to have OrderID, ProductName inside of a combobox, UnitPrice and Quantity columns.第二种形式是订单详细信息,我应该在组合框中包含 OrderID、ProductName、UnitPrice 和 Quantity 列。 I have managed to create all of them, set their values through SQL using Dapper, but I am having a hard time getting the combobox to display the value of ProductID.我已经设法创建了所有这些,并使用 Dapper 通过 SQL 设置了它们的值,但是我很难让组合框显示 ProductID 的值。

To simplify: I want the combobox to show the name of the product with the ProductID that is matching to the one given in the order details.为简化起见:我希望组合框显示产品名称,其 ProductID 与订单详细信息中给出的名称相匹配。 If I change the Product inside of combobox, I need it to take the combobox ProductID value and change it in Order Details.如果我更改组合框内的产品,我需要它获取组合框 ProductID 值并在订单详细信息中更改它。 If the order is a new one with no details, it should set it by default for the ProductID to be 1.如果订单是一个没有详细信息的新订单,它应该默认将 ProductID 设置为 1。

The combobox is inside of a DataGridView that is using a list of order details created by Dapper.组合框位于使用 Dapper 创建的订单详细信息列表的 DataGridView 内。 Everything else works like a charm, I am just having a lot of trouble with the combobox.其他一切都像魅力一样,我只是在组合框上遇到了很多麻烦。

Here is some code, I will add more if needed:这是一些代码,如果需要我会添加更多:

This is the code for the combobox itself这是组合框本身的代码

private void fillcombobox()
        {
            DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
            combo.HeaderText = "ProductName";
            DataAccess dt = new DataAccess();
            products = dt.GetAllProducts();
            combo.DataSource = products;
            combo.DisplayMember = "ProductName";
            combo.ValueMember = "ProductID";
            orderdetailsGridView.Columns.Add(combo);
            combo.DisplayIndex = 0;
        }

Here is the OrderDetails class这是 OrderDetails 类

public class OrderDetails
    {
        public int OrderID { get; set; }
        public int ProductID { get; set; }
        public decimal UnitPrice { get; set; }
        public int Quantity { get; set; }
    }

Here is the Product class这是产品类

public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public decimal UnitPrice { get; set; }
        public int UnitsInStock { get; set; }
    }

Here is the query for the GetAllProducts这是对 GetAllProducts 的查询

public List<Product> GetAllProducts()
        {
            using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(Helper.CnnVal("ShopDB")))
            {
                var output = connection.Query<Product>("select * from Products").ToList();
                return output;
            }
        }

在此处输入图片说明

After you set the data source for the combo you can attach yourself to the row added event of the orderdetailsGridView.为组合设置数据源后,您可以将自己附加到 orderdetailsGridView 的行添加事件。 In the event listener you can set the value of the combo column.在事件侦听器中,您可以设置组合列的值。

Attach to event附加到事件

orderdetailsGridView.RowsAdded += DataGridView_RowsAdded;

Event listener can then go something like this:然后事件侦听器可以像这样:

     private void DataGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        ((DataGridViewComboBoxCell)((DataGridView)sender).Rows[e.RowIndex].Cells["ProductName"]).Value =
            ((List<OrderDetails>)dataGridView1.DataSource)[e.RowIndex].ProductID;

    }

Since you are just doing products from your .Query class, just update your class structure to have a read-only property (having only a getter) that returns the formatted value for presentation purposes only in your combobox.由于您只是从您的 .Query 类中制作产品,因此只需更新您的类结构以具有只读属性(只有一个 getter),该属性仅在您的组合框中返回用于演示目的的格式化值。

public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public decimal UnitPrice { get; set; }
        public int UnitsInStock { get; set; }
        public string ShowProductAndId 
           { get { return ProductName + " (" + ProductID + ")"; } }

    }

Then, set your display value to the new property "ShowProductAndId".然后,将您的显示值设置为新属性“ShowProductAndId”。

CLARIFICATION PLEASE请澄清

It appears we are not communicating well.看来我们沟通不畅。 You are asking about the product ID, which is what the value member will have (Product ID), but the Display member shows the actual product name.您正在询问产品 ID,这是价值成员将拥有的(产品 ID),但显示成员显示实际产品名称。 If this is a detail screen for a given order and you are listing the items someone ordered, I would expect something different for your query based on the single Order # being looked into.如果这是给定订单的详细信息屏幕,并且您正在列出某人订购的商品,我希望您的查询基于正在调查的单个订单编号有所不同。 I would grab both the detail line item from the order detail AND the product ID as reference and its product name.我会从订单详细信息和产品 ID 中获取详细信息行项目作为参考及其产品名称。 Use an OrderDetail class that has all the parts actually ordered.使用包含实际订购的所有部件的 OrderDetail 类。 Such a query might be这样的查询可能是

select
      OD.*,
      P.ProductName
   from
      OrderDetail OD
         JOIN Product P
            on OD.ProductID = P.ProductID
   where
      OD.OrderID = @selectedOrderToGetDetailsFor

Then, I would have your ShowOrderDetail be derived from your OrderDetail so you can tack-on the now expected product name as part of its result, something like below will get all properties of your NORMAL OrderDetail, but also include the Product name at the same time as a result set from the query above.然后,我会让您的 ShowOrderDetail 从您的 OrderDetail 派生,以便您可以添加现在预期的产品名称作为其结果的一部分,如下所示将获得您的 NORMAL OrderDetail 的所有属性,但同时还包括产品名称时间作为上述查询的结果集。

public class ShowOrderDetail : OrderDetail
{
   public string ProductName { get; set; }
}

Then, you could have the Order Details combo reference the ProductName from this class and not the ALL PRODUCTS.然后,您可以让 Order Details 组合引用此类中的 ProductName 而不是 ALL PRODUCTS。

Not necesssarily a great design plan.不一定是一个伟大的设计计划。 Dont know why you might have an order of 5 widgets, product ID = 3, then let the user see the line and let them change it to 5 somethingElse, product ID = 17. Doesn't make sense.不知道为什么您可能有 5 个小部件的订单,产品 ID = 3,然后让用户看到该行并让他们将其更改为 5 somethingElse,产品 ID = 17。没有意义。 But you COULD just have the Product Name as shown on the row since you now have it available as the result set and the user would not have the option to change the ordered item.但是您可以只拥有显示在行上的产品名称,因为您现在可以将其作为结果集使用,而用户将无法更改订购的项目。

FINAL COMMENTS (hopeful?)最后评论(希望?)

So, now I see what you have with your image.所以,现在我看到了你的形象。 You basically need TWO bindings.您基本上需要两个绑定。 One for the source of records to display, but the SELECTED VALUE (ID) needs to be bound to the ID key from the records in your data.一个用于显示记录的来源,但需要将 SELECTED VALUE (ID) 绑定到数据中记录的 ID 键。 It has been quite a while since I did C# Windows Forms and was not doing that much before I got into C#/WPF, so my bindings there are not as strong.自从我使用 C# Windows Forms 已经有一段时间了,在我进入 C#/WPF 之前并没有做那么多,所以我的绑定没有那么强。 I can try to play around with it some, but cant today.我可以尝试使用它一些,但今天不能。

However, take a look here . 但是,看看这里 This other answer shows WinForms binding in code, similar to what you are doing to prepare your combobox.这个另一个答案在代码中显示了 WinForms 绑定,类似于您准备组合框的操作。 But you probably want to add an additional binding to the source that your selected detail record is and ITS product ID for the refresh.但您可能希望向所选详细记录所在的源和 ITS 产品 ID 添加附加绑定以进行刷新。

So, the binding of the combobox would have TWO sources.因此,组合框的绑定将有两个来源。 The primary you already have for the list, but a second for the selected value binding to be bound to the list of details that the data grid of all items on the order, and to the PATH of the ProductID on that order detail record.您已经拥有列表的主要内容,但第二个用于将所选值绑定绑定到订单上所有项目的数据网格的详细信息列表,以及该订单详细信息记录上 ProductID 的 PATH。

Look at how they are creating a "BindingSource", and setting that to the list.看看他们如何创建“BindingSource”,并将其设置到列表中。 In your case, you want to point to your order details list.在您的情况下,您希望指向您的订单详细信息列表。 But then, the data member/path you want is the "ProductID" as it is on the detail record.但是,您想要的数据成员/路径是详细记录中的“ProductID”。

Hope I could help you more, but this SHOULD help push you to what you need.希望我能帮助你更多,但这应该有助于推动你达到你所需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM