2015-06-19 69 views
0

我希望有人能幫助我有我絕對狼狽一個不起眼的問題DataGridViewComboBoxColumn改變爲不同的值。綁定的DataGridView:當我點擊外面

我希望設置一個DataGridView,它允許用戶從DataGridViewComboBoxColumn中選擇一個選項,併爲DataGridView的數據源選擇一個對象,以便用戶在ComboBox中選擇的對象進行更新。

[NB我希望DataGridViewComboBoxColumn在下拉菜單中顯示多個屬性,因此我使用DataTable作爲DataGridViewComboBoxColumn數據源。換句話說,我希望他們看到一個描述,它是其他屬性組合在一起的描述。]

我的代碼有效,但是當我在ComboBox單元格外單擊時,值會自動設置(它會被設置回BindingList中的第一項)。我無法讓它堅持用戶選擇的價值。最終,將錯誤的對象實例分配給DataGridView的dataSource。

我會張貼一張照片,但我沒有足夠的代表。

所以我的問題是,爲什麼DataGridViewComboBoxColumn開關在其數據源(數據表)的第一個項目,當我點擊細胞外。我怎樣才能讓它保持我選擇的選項,在單元格中。我絕對是BAFFLED。

我希望這沒關係發佈這麼多的代碼到StackOverflow的網站,無需惱人的每一個人。我試圖創建適當的通用示例來幫助其他靈魂試圖找出如何使用DataGridViewComboBoxColumn選擇對象並將其分配給另一個對象的屬性。所以希望這對其他人有用。如果有人需要解決這類問題,我還試圖讓它更容易重新創建。

我已經嘗試了所有方式的事情,包括使用List作爲DataGridViewComboBoxColumn的數據源,使用CurrentCellDirtyStateChanged事件做事 - 都無濟於事。

這裏是我的2類:

public class CarPartChoice 
    { 
     public string Name { get; set; } 
     public int Value { get; set; } 
     public string Comment {get; set;} 

     public CarPartChoice(string name, int value, string comment) 
     { 
      Name = name; 
      Value = value; 
      Comment = comment; 
     } 
    } 

    public class Car 
    { 
     public string Manufacturer { get; set; } 
     public string Model { get; set; } 
     public CarPartChoice WheelChoice {get; set;} 

     public Car(string maker, string model, CarPartChoice wheel) 
     { 
      Manufacturer = maker; 
      Model = model; 
      WheelChoice = wheel; 
     } 

     public Car(string maker, string model) 
     { 
      Manufacturer = maker; 
      Model = model; 
     } 
    } 

    public static class GlobalVariables 
    { 
     public static BindingList<CarPartChoice> GlobalChoiceList { get; set; } 
     public static BindingList<Car> GlobalCarsList { get; set; } 
    } 

下面是我創造我的dataGridView:

 private void Form1_Load(object sender, EventArgs e) 
     { 
      //Setup the wheel choices to be selected from the DataGridViewComboBoxColumn. 
      CarPartChoice myWheelChoice = new CarPartChoice("Chrome", 19, "This is the chromes wheels option."); 
      CarPartChoice myWheelChoice2 = new CarPartChoice("HubCaps", 16, "This is the nasty plastic hubcaps option."); 
      BindingList<CarPartChoice> tempBLChoice = new BindingList<CarPartChoice>(); 
      tempBLChoice.Add(myWheelChoice); 
      tempBLChoice.Add(myWheelChoice2); 
      GlobalVariables.GlobalChoiceList = tempBLChoice; 

      //Setup the cars to populate the datagridview. 
      Car car1 = new Car("Vauxhall", "Astra"); 
      Car car2 = new Car("Mercedes", "S-class"); 
      BindingList<Car> tempListCars = new BindingList<Car>(); 
      tempListCars.Add(car1); 
      tempListCars.Add(car2); 
      GlobalVariables.GlobalCarsList = tempListCars; 

      dataGridView1.AutoGenerateColumns = false; 
      dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged); 

      // Set up 2 DataGridViewTextBox columns, one to show the manufacturer and the other to show the model. 
      DataGridViewTextBoxColumn manufacturer_col = new DataGridViewTextBoxColumn(); 
      manufacturer_col.DataPropertyName = "Manufacturer"; 
      manufacturer_col.Name = "Manufacturer"; 
      manufacturer_col.HeaderText = "Manufacturer"; 
      DataGridViewTextBoxColumn model_col = new DataGridViewTextBoxColumn(); 
      model_col.DataPropertyName = "Model"; 
      model_col.Name = "Model"; 
      model_col.HeaderText = "Model"; 

      // Create a DataTable to hold the Wheel options available for the user to choose from. This DT will be the DataSource for the 
      // ...combobox column 
      DataTable wheelChoices = new DataTable(); 
      DataColumn choice = new DataColumn("Choice", typeof(CarPartChoice)); 
      DataColumn choiceDescription = new DataColumn("Description", typeof(String)); 
      wheelChoices.Columns.Add(choice); 
      wheelChoices.Columns.Add(choiceDescription); 
      foreach (CarPartChoice wheelchoice in GlobalVariables.GlobalChoiceList) 
      { 
       wheelChoices.Rows.Add(wheelchoice, wheelchoice.Name + " - " + wheelchoice.Value.ToString() + " - " + wheelchoice.Comment); 
      } 

      // Create the Combobox column, populated with the wheel options so that user can pick one. 
      DataGridViewComboBoxColumn wheelOption_col = new DataGridViewComboBoxColumn(); 
      wheelOption_col.DataPropertyName = "WheelChoice"; 
      wheelOption_col.Name = "WheelChoice"; 
      wheelOption_col.DataSource = wheelChoices; 
      wheelOption_col.ValueMember = "Choice"; 
      wheelOption_col.DisplayMember = "Description"; 
      wheelOption_col.ValueType = typeof(CarPartChoice); 

      // Add the columns and set the datasource for the DGV. 
      dataGridView1.Columns.Add(manufacturer_col); 
      dataGridView1.Columns.Add(model_col); 
      dataGridView1.Columns.Add(wheelOption_col); 
      dataGridView1.DataSource = GlobalVariables.GlobalCarsList; 
     } 

更新: 我曾嘗試使用 「的BindingSource」 對象和設置的BindingSource的數據源到DataTable。這沒有什麼區別。我也嘗試讓汽車實施「INotifyPropertyChanged」界面,但沒有任何區別。

的一兩件事,如果我注意到的是,在DataGridView的汽車項目被打的WheelChoice屬性更新。 Car對象更新了我從ComboBox中選擇的值。我認爲這只是一個顯示問題,而DataGridViewComboBoxColumn只是沒有填充正確的值。仍然困惑。

+0

這是總是發生點擊或只有當下拉列表仍然顯示時? – TaW

+0

解決方法:添加空的'DataError'事件處理程序:'this.dataGridView1.DataError + =(sender,e)=> {};' – Fabio

+0

Hi TaW:發生後,我從下拉列表中選擇並單擊另一個控件。換句話說,我已經從下拉菜單中選擇了我的選項,這導致了該字段被填充並且下拉菜單將被移除。我選擇的選項仍保留在控件中,直到我點擊下拉框外的任何地方。只要我這樣做,控件中的值就會自動更改。 –

回答

0

感謝那些留下評論的人。我最終找到了答案。

答案只適用於我爲我的「CarPartChoice」類(即用於通過單擊ComboBoxColumn提供要查找的項的類)定義重寫的「ToString()」方法。我猜想,當我將控制權從控制檯移開時,我的電池格式化了一個漂亮的字符串。

因此,對於任何想要在將來這樣做的人,下面是一個完整的示例,說明如何使用datagridview更新某個類的對象列表,並使用DataGridViewComboBoxColumn爲用戶提供選擇對象以及他們選擇的對象(他們從下拉列表中選擇)填充到列表中(具體而言:在列表中的對象的字段中,該對象的類型是由用戶選擇的對象的類型在下拉菜單中)。是的,我知道這是一個非常可怕的句子。

下面是完成此任務的完整代碼(我原以爲這是人們經常想要做的事)。

最親切的問候。

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      //Setup the wheel choices to be selected from the DataGridViewComboBoxColumn. 
      CarPartChoice myWheelChoice = new CarPartChoice("Chrome", 19, "This is the chromes wheels option."); 
      CarPartChoice myWheelChoice2 = new CarPartChoice("HubCaps", 16, "This is the nasty plastic hubcaps option."); 
      CarPartChoice myWheelChoice3 = new CarPartChoice("Iron", 15, "These are metal wheels."); 
      CarPartChoice myWheelChoice4 = new CarPartChoice("Spoked", 15, "This is the fancy classic hubcaps option."); 
      CarPartChoice myWheelChoice5 = new CarPartChoice("solid", 13, "This wheels has no spokes or holes."); 
      CarPartChoice myWheelChoice6 = new CarPartChoice("SpaceHubCaps", 17, "Newly developed space hubcaps."); 

      BindingList<CarPartChoice> tempBLChoice = new BindingList<CarPartChoice>(); 
      tempBLChoice.Add(myWheelChoice); 
      tempBLChoice.Add(myWheelChoice2); 
      tempBLChoice.Add(myWheelChoice3); 
      tempBLChoice.Add(myWheelChoice4); 
      tempBLChoice.Add(myWheelChoice5); 
      tempBLChoice.Add(myWheelChoice6); 

      GlobalVariables.GlobalChoiceList = tempBLChoice; 

      //Setup the cars to populate the datagridview. 
      Car car1 = new Car("Vauxhall", "Astra"); 
      Car car2 = new Car("Mercedes", "S-class"); 
      BindingList<Car> tempListCars = new BindingList<Car>(); 
      tempListCars.Add(car1); 
      tempListCars.Add(car2); 
      GlobalVariables.GlobalCarsList = tempListCars; 

      dataGridView1.AutoGenerateColumns = false; 
      dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged); 


      // Set up 2 DataGridViewTextBox columns, one to show the manufacturer and the other to show the model. 
      DataGridViewTextBoxColumn manufacturer_col = new DataGridViewTextBoxColumn(); 
      manufacturer_col.DataPropertyName = "Manufacturer"; 
      manufacturer_col.Name = "Manufacturer"; 
      manufacturer_col.HeaderText = "Manufacturer"; 
      DataGridViewTextBoxColumn model_col = new DataGridViewTextBoxColumn(); 
      model_col.DataPropertyName = "Model"; 
      model_col.Name = "Model"; 
      model_col.HeaderText = "Model"; 

      // Create a DataTable to hold the Wheel options available for the user to choose from. This DT will be the DataSource for the 
      // ...combobox column 
      DataTable wheelChoices = new DataTable(); 
      DataColumn choice = new DataColumn("Choice", typeof(CarPartChoice)); 
      DataColumn choiceDescription = new DataColumn("Description", typeof(String)); 
      wheelChoices.Columns.Add(choice); 
      wheelChoices.Columns.Add(choiceDescription); 

      foreach (CarPartChoice wheelchoice in GlobalVariables.GlobalChoiceList) 
      { 
       wheelChoices.Rows.Add(wheelchoice, wheelchoice.Name + " - " + wheelchoice.Value.ToString() + " - " + wheelchoice.Comment); 
      } 

      // Create the Combobox column, populated with the wheel options so that user can pick one. 
      DataGridViewComboBoxColumn wheelOption_col = new DataGridViewComboBoxColumn(); 
      wheelOption_col.DataPropertyName = "WheelChoice"; 
      wheelOption_col.DataSource = wheelChoices; 
      wheelOption_col.ValueMember = "Choice"; 
      wheelOption_col.DisplayMember = "Description"; 
      wheelOption_col.ValueType = typeof(CarPartChoice); 

      // Add the columns and set the datasource for the DGV. 
      dataGridView1.Columns.Add(manufacturer_col); 
      dataGridView1.Columns.Add(model_col); 
      dataGridView1.Columns.Add(wheelOption_col); 
      dataGridView1.DataSource = GlobalVariables.GlobalCarsList; 
     } 

     void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
     { 
      var grid = sender as DataGridView; 
      if (grid.IsCurrentCellDirty) 
       grid.CommitEdit(DataGridViewDataErrorContexts.Commit); 
     } 
    } 

    public class CarPartChoice 
    { 
     public string Name { get; set; } 
     public int Value { get; set; } 
     public string Comment { get; set; } 

     public CarPartChoice(string name, int value, string comment) 
     { 
      Name = name; 
      Value = value; 
      Comment = comment; 
     } 

     public override string ToString() 
     { 
      return Name.ToString() + " - " + Value.ToString() + " - " + Comment.ToString(); 
     } 
    } 

    public class Car 
    { 
     public string Manufacturer { get; set; } 
     public string Model {get; set; } 
     public CarPartChoice WheelChoice { get; set; } 

     public Car(string maker, string model, CarPartChoice wheel) 
     { 
      Manufacturer = maker; 
      Model = model; 
      WheelChoice = wheel; 
     } 

     public Car(string maker, string model) 
     { 
      Manufacturer = maker; 
      Model = model; 
     } 
    } 

    public static class GlobalVariables 
    { 
     public static BindingList<CarPartChoice> GlobalChoiceList { get; set; } 
     public static BindingList<Car> GlobalCarsList { get; set; } 
    }