#c# #winforms #data-binding #datagridview #datatable
#c# #winforms #привязка данных #datagridview #datatable
Вопрос:
Я пытаюсь что-то настроить в DataGridView
. Кажется, это должно быть довольно просто, но у меня проблемы. Я хочу отобразить три столбца:
- CodeID
- Кодовое имя
- ComboBox с отображаемым элементом TypeName, значением TypeID
Я хочу иметь возможность выбирать из всех возможных значений TypeName
. Вот моя дилемма:
Если я загружу все это в один DataTable
и установлю DataGridView
как DataSource
, я могу отобразить существующую TypeName
для этой записи, но поле со списком не будет содержать никаких других значений. Если я установлю DataSource
для DataGridViewComboBoxColumn
отдельного DataTable
, который включает все возможные TypeNames
, существующее значение не отображается.
DataGridView
действительно раздражает работа, поэтому будет оценено либо решение для этого, либо жизнеспособная альтернатива.
Редактировать: похоже, проблема вызвана тем, что я хочу иметь отдельный элемент для DisplayMember
and ValueMember
. Работает следующее, если я не беспокоюсь о том, чтобы установить ID
как ValueMember
:
var typeColumn = new DataGridViewComboBoxColumn
{
DataSource = typeList,
DisplayMember = "Type",
ValueMember = "Type",
DataPropertyName = "Type"
}
Если я сделаю следующее, будут выбраны правильные типы, но я не могу изменить выбор в поле со списком:
var typeColumn = new DataGridViewComboBoxColumn
{
DataSource = typeList,
DisplayMember = "Type",
ValueMember = "TypeID",
DataPropertyName = "TypeID"
}
Если я использую следующее, я получаю FormatException
сообщение об ошибке при попытке заполнения:
var typeColumn = new DataGridViewComboBoxColumn
{
DataSource = typeList,
DisplayMember = "Type",
ValueMember = "TypeID",
DataPropertyName = "Type"
}
редактировать: typeList
простое DataTable
заполняется следующим:
SELECT DISTINCT IT.InsuranceTypeID, IT.[Type]
FROM InsuranceType IT
WHERE IT.ClientID = @ClientID
ORDER BY [Type]
Комментарии:
1. Устанавливаете ли вы DataPropertyName в DGVCBC? Кроме того, значок профиля epic. social.msdn.microsoft.com/forums/en-US/winformsdatacontrols /…
2. Можете ли вы опубликовать, как вы настраиваете
typeList
и структуру, которую вы добавляете в список? ТипыDataPropertyName
иValueMember
должны быть одинаковыми, вероятно, поэтому вы получаете исключение в последнем примере.
Ответ №1:
У меня была похожая (я думаю) проблема, и решением для меня было установить DataSource
для DataGridViewComboBoxColumn
перед установкой DataSource
для DataGridView
.
В моем случае моими источниками данных являются a List<T>
и a BindingList<T>
соответственно, но он должен работать так же с таблицами данных:
DataGridViewComboBoxColumn categoryColumn = (DataGridViewComboBoxColumn)_ItemsGrid.Columns["CategoryID"];
categoryColumn.DataSource = categories;
_ItemsGrid.DataSource = items;
Комментарии:
1. К сожалению, это не помогло.
2. Это очень помогло мне при использовании Eloquera и привязке некоторого сложного класса к datagrid. Спасибо!
3. Этот ответ был волшебным для меня, найдя его 10 лет спустя.
Ответ №2:
Хорошо, я привел пример ClientInfo
, и InsuranceDetails
я думаю, что он может имитировать то, что вы пытаетесь сделать. Дайте мне знать, если эти детали не совсем верны. В этом примере будет заполнено DataGridViewComboBox
и установлено значение на основе InsuranceDetails
(в частности, в: InsurDetailz = all_insurance_types[2]
)
public partial class Form1 : Form
{
private ClientInfo _myClient;
private BindingList<InsuranceDetails> all_insurance_types =
new BindingList<InsuranceDetails>();
public Form1()
{
InitializeComponent();
DataGridView grid = new DataGridView();
grid.Dock = DockStyle.Fill;
grid.AutoGenerateColumns = true;
all_insurance_types.Add(new InsuranceDetails(1, "Health"));
all_insurance_types.Add(new InsuranceDetails(2, "Home"));
all_insurance_types.Add(new InsuranceDetails(3, "Life"));
var col = new DataGridViewComboBoxColumn
{
DataSource = all_insurance_types,
HeaderText = "Insurance Type",
DataPropertyName = "InsurDetailz",
DisplayMember = "ItType",
ValueMember = "Self",
};
_myClient = new ClientInfo {
InsurDetailz = all_insurance_types[2], Name = "Jimbo" };
grid.Columns.Add(col);
grid.DataSource = new BindingList<ClientInfo> { _myClient };
this.Controls.Add(grid);
this.FormClosing = new FormClosingEventHandler(Form1_FormClosing);
}
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// make sure its updated
InsuranceDetails c = _myClient.InsurDetailz;
string name = _myClient.Name;
// Place breakpoint here to see the changes in _myClient
throw new NotImplementedException();
}
}
class ClientInfo
{
public string Name { get; set; }
public InsuranceDetails InsurDetailz { get; set; }
}
class InsuranceDetails
{
public int InsuranceTypeID { get; set; }
public String ItType { get; set; }
public InsuranceDetails Self { get { return this; } }
public InsuranceDetails(int typeId, String itType)
{
this.InsuranceTypeID = typeId;
this.ItType = itType;
}
}
Комментарии:
1. Секрет заключается в
Self
свойстве.