Для таблицы данных Winforms .NET я хотел бы, чтобы столбец комбинированного списка имел различный набор значений для каждой строки. - PullRequest
4 голосов
/ 27 января 2011

У меня есть DataGridView, который я привязываю к POCO. У меня привязка данных работает нормально. Однако я добавил столбец со списком, который я хочу, чтобы он был разным для каждой строки. В частности, у меня есть сетка купленных предметов, некоторые из которых имеют размеры (например, Adult XL, Adult L), а другие предметы не имеют размеров (например, Car Magnet.)

По сути, я хочу изменить ИСТОЧНИК ДАННЫХ для столбца со списком в сетке данных. Это может быть сделано?

К какому событию я могу подключиться, что позволило бы мне изменять свойства определенных столбцов ДЛЯ КАЖДОГО РЯДА? Приемлемой альтернативой является изменение свойства, когда пользователь щелкает или вкладывает строку. Что это за событие?

Сет

EDIT
Мне нужно больше помощи с этим вопросом. С помощью Triduses я ТАК близко, но мне нужно немного больше информации.

Во-первых, в соответствии с вопросом, действительно ли событие CellFormatting является лучшим / единственным событием для изменения источника данных для столбца со списком. Я спрашиваю, потому что я делаю что-то довольно ресурсоемкое, а не просто форматирую ячейку.

Во-вторых, событие форматирования ячейки вызывается просто при наведении курсора мыши на ячейку. Я попытался установить свойство FormattingApplied внутри моего if-block , а затем проверяю его в if-test , но это возвращает странное сообщение об ошибке. Моя идеальная ситуация - применить источник данных для поля со списком один раз для каждой строки, а затем покончить с этим.

Наконец, чтобы установить источник данных для поля со списком, я должен иметь возможность привести ячейку внутри моего блока if к типу DataGridViewComboBoxColumn, чтобы я мог заполнить его строками или установить источник данных или что-то еще. Вот код, который у меня есть сейчас.

Private Sub ProductsDataGrid_CellFormatting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles ProductsDataGrid.CellFormatting

    If e.ColumnIndex = ProductsDataGrid.Columns("SizeDGColumn").Index Then ' AndAlso Not e.FormattingApplied Then
        Dim product As LeagueOrderProductInfo = DirectCast(ProductsDataGrid.Rows(e.RowIndex).DataBoundItem, LeagueOrderProductInfo)
        Dim sizes As LeagueOrderProductSizeList = product.ProductSizes
        sizes.RemoveSizeFromList(_parentOrderDetail.SizeID)

        'WHAT DO I DO HERE TO FILL THE COMBOBOX COLUMN WITH THE sizes collection.

    End If

End Sub

Пожалуйста, помогите. Я полностью застрял, и этот предмет задачи должен был занять час, а сейчас у меня 4+ часа. Кстати, я также открыт для решения этой проблемы, взяв с собой совершенно другое направление (пока я могу сделать это быстро.)

Сет

Ответы [ 5 ]

3 голосов
/ 28 января 2011

К сожалению, его нет.Вам нужно будет использовать событие CellFormatting .

, которое сработает для каждой ячейки, но вы можете выяснить, находитесь ли вы в правом столбце, проверив столбециндекс ячейки, и затем вы можете сделать свою логику, если вы находитесь в столбце, с которым хотите работать.

Если вы решите, что хотите изменить его, когда они выбирают строку, а не когда она отображается,вместо этого вы можете использовать RowEnter.

Вот пример кода того, как использовать это событие.Этот устанавливает столбец, чтобы иметь изображение в нем.

 Private Sub dgActiveOccurrences_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgActiveOccurrences.CellFormatting
        If e.ColumnIndex = dgActiveOccurrences.Columns("colActiveUnreadFlag").Index Then
            Dim occ As Occurrence = DirectCast(dgActiveOccurrences.Rows(e.RowIndex).DataBoundItem, Occurrence)
            If occ.LastReadBy <> OccurrenceSession.Self.UserManager.MyStaffRecord.StaffId Then
                e.Value = My.Resources.Icon_UnreadFlag
            End If
        End If
End Sub
2 голосов
/ 03 февраля 2011

Я не пытался поймать событие, чтобы изменить отображаемые значения в выпадающем списке для каждой строки ... Взгляните на этот подход (пример), он очень простой и простой в реализации и выполняет именно то, что вы хотите imho.:

  1. Объявление класса Item с двумя простыми свойствами (Имя, Тип)

  2. Создание DataGridView с двумя столбцами (один для имени, а второй для типа с ColumnType = DataGridViewComboBoxColumn и dataPropertyName = Type)

  3. «Присоединить» ваш (я полагаю) список документов к DataGridView

  4. И после этого петля одноразовая только по вашей коллекции строк; получить DataGridViewComboBoxColumn для этой строки ; Измените его свойство items в соответствии с критериями, указанными для poco в этой строке .

Я оставляю за вами право взять poco для конкретной строки или, в качестве альтернативы, прочитать некоторые свойства из жестко закодированных столбцов в строке ...

Вот пример кода:

namespace DataGridViewCustomComboboxItemsPerRow
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            List<int> types = new List<int>();
            List<Item> items = new List<Item>();
            Item item;
            for (int i = 0; i < 100; i++)
            {
                item = new Item();
                item.Name = "Item" + i.ToString();
                item.Type = i;

                items.Add(item);
                types.Add(i);
            }

            //typeDataGridViewComboBoxColumn.DataSource = types;
            itemBindingSource.DataSource = items;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            DataGridViewComboBoxCell dgvc;

            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                dgvc = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells[1];

                // Your CUSTOM code here, I just did some stupid thing here...
                dgvc.Items.Add(i - 1);
                dgvc.Items.Add(i);
                dgvc.Items.Add(i + 1);
            }
        }
    }

    public class Item
    {
        private string _name;
        private int _type;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public int Type
        {
            get { return _type; }
            set { _type = value; }
        }
    }
}

Код написан на C #, но довольно прост, поэтому я думаю, что он не вызовет проблем в VB.NET. И этот код действительно выполняет однократный цикл (O (n)) для настройки ваших комбо для разных строк и чем это делается.

Надеюсь, это поможет. Юп.

0 голосов
/ 06 февраля 2011

Вы можете сделать это с событием CellBeginEdit .Обработайте событие, проверьте, является ли редактируемый столбец вашим столбцом DataGridViewComboBox, и измените элементы в выпадающем списке.

Это может не работать, если вы привязываете источник данных к выпадающему списку.Я только попробовал это вручную добавить список элементов:

void grid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    if (grid.Columns[e.ColumnIndex].Name == "MyComboColumn")
    {
        // get the value of a different cell in this row that will be used to determine which values are in the combobox
        string other_value = grid[0, e.RowIndex].Value.ToString();

        // get the combobox cell being edited
        DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)grid[e.ColumnIndex, e.RowIndex];

        // update the list of items in the combobox
        cell.Items.Clear();
        if (other_value == "something")
            cell.Items.AddRange(new object[] { "Value1", "Value2" });
        else
            cell.Items.AddRange(new object[] { "Value3", "Value4" });

    }
}

Примечание: этот код не проверен, на данный момент я не на своей машине для разработки.

0 голосов
/ 04 февраля 2011

Если вы не можете добавить строку в эту сетку, вы можете использовать событие DataBindingComplete, и это событие вызывается, когда сетка завершает привязку своих данных, и если вы можете добавить строки, вам необходимо дополнительно использовать событие NewRowNeeded для этого событиясрабатывает, если вы нажмете на новую строку в нижней части сетки, и вы не будете беспокоиться о заполнении одной и той же комбинации несколько раз

0 голосов
/ 03 февраля 2011

Я не уверен, возможно ли это для вас. Можете ли вы попробовать то же самое в dataGridView1_DataBindingComplete событие

foreach (DataGridViewRow var in dataGridView1.Rows)
{
      if (var.Cells[0] is DataGridViewComboBoxCell)
      {
          (var.Cells[0] as DataGridViewComboBoxCell).Items.Add("first col values");
      }
      if (var.Cells[1] is DataGridViewComboBoxCell)
      {
          (var.Cells[1] as DataGridViewComboBoxCell).Items.Add("second col values");
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...