Как установить AutoSizeMode столбцов в обработчике ParentChanged без исключения DataError с контекстом: «Форматирование, PreferredSize»? - PullRequest
0 голосов
/ 25 марта 2019

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

  1. HandleCreated;
  2. VisibleChanged;
  3. ParentChanged.

Поэтому я поместил код, который устанавливает все столбцы для заполнения таблицы, в обработчик ParentChanged. Но я все еще получаю эту DataError.

Я не смог найти похожий вопрос, который мне помогает.

Я начал обрабатывать DataError самостоятельно, чтобы увидеть подробности ошибки. То, что я нашел, это:

  • Контекст: Formatting, PreferredSize.
  • Столбец: столбец ComboBox, который принимает новые записи, введенные в меню при вводе.
  • Сообщение: «DataGridViewComboBoxCell недействителен».
  • Одно окно сообщения для каждой строки, которая имеет непустую строку в качестве значения в этом столбце. Примечание. В столбце ComboBox есть источник данных, представляющий собой список чего-то другого, кроме строк. Я установил DisplayMember и ValueMember, а также ValueType на typeof(string) (Если я установил ListControlItem, я получу DataError -s о контексте Display, и я не знаю, если я следует продолжить на этом треке).

Моя программа довольно большая, поэтому я не знаю, какую часть кода показывать. Вот трассировка стека вызова OnDataError:

cs_timed_silver.ClockDataGridView.OnDataError(bool displayErrorDialogIfNoHandler = true, System.Windows.Forms.DataGridViewDataErrorEventArgs e = {System.Windows.Forms.DataGridViewDataErrorEventArgs}) Line 2016
    at E:\Lucru\cs-timed-silver\cs-timeout\SplitterPanels\ClockDataGridView.cs(2016)
System.Windows.Forms.DataGridView.OnDataErrorInternal(System.Windows.Forms.DataGridViewDataErrorEventArgs e)
System.Windows.Forms.DataGridViewComboBoxCell.GetFormattedValue(object value, int rowIndex = 0, ref System.Windows.Forms.DataGridViewCellStyle cellStyle = {System.Windows.Forms.DataGridViewCellStyle}, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter = null, System.Windows.Forms.DataGridViewDataErrorContexts context = Formatting | PreferredSize)
System.Windows.Forms.DataGridViewComboBoxCell.GetPreferredSize(System.Drawing.Graphics graphics = {System.Drawing.Graphics}, System.Windows.Forms.DataGridViewCellStyle cellStyle, int rowIndex, System.Drawing.Size constraintSize)
System.Windows.Forms.DataGridViewCell.GetPreferredWidth(int rowIndex, int height)
System.Windows.Forms.DataGridViewColumn.GetPreferredWidth(System.Windows.Forms.DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight = true)
System.Windows.Forms.DataGridView.AutoResizeColumnInternal(int columnIndex = 6, System.Windows.Forms.DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal, bool fixedHeight)
System.Windows.Forms.DataGridView.OnAutoSizeColumnModeChanged(System.Windows.Forms.DataGridViewAutoSizeColumnModeEventArgs e = {System.Windows.Forms.DataGridViewAutoSizeColumnModeEventArgs})
System.Windows.Forms.DataGridView.OnAutoSizeColumnModeChanged(System.Windows.Forms.DataGridViewColumn dataGridViewColumn, System.Windows.Forms.DataGridViewAutoSizeColumnMode previousInheritedMode)
System.Windows.Forms.DataGridViewColumn.AutoSizeMode.set(System.Windows.Forms.DataGridViewAutoSizeColumnMode value)
cs_timed_silver.ClockDataGridView.Cms_ResizeColumnsToFill(object sender = {System.Windows.Forms.ToolStripMenuItem}, System.EventArgs e = {System.EventArgs}) Line 200
    at E:\Lucru\cs-timed-silver\cs-timeout\SplitterPanels\ClockDataGridView.cs(200)
cs_timed_silver.ClockDataGridView.Item_CheckedChanged(object sender = {System.Windows.Forms.ToolStripMenuItem}, System.EventArgs e = {System.EventArgs}) Line 1003
    at E:\Lucru\cs-timed-silver\cs-timeout\SplitterPanels\ClockDataGridView.cs(1003)
System.Windows.Forms.ToolStripMenuItem.OnCheckedChanged(System.EventArgs e)
System.Windows.Forms.ToolStripMenuItem.CheckState.set(System.Windows.Forms.CheckState value)
System.Windows.Forms.ToolStripMenuItem.Checked.set(bool value)
cs_timed_silver.MainForm.ApplySetting(cs_timed_silver.SettingData sd = {cs_timed_silver.SettingData}) Line 650
    at E:\Lucru\cs-timed-silver\cs-timeout\Views\MainForm.cs(650)
cs_timed_silver.MainForm.Settings_SettingValueChange(object sender = {cs_timed_silver.SettingData}, System.EventArgs e = {System.EventArgs}) Line 660
    at E:\Lucru\cs-timed-silver\cs-timeout\Views\MainForm.cs(660)
cs_timed_silver.SettingDataCollection.Ds_Changed(object sender = {cs_timed_silver.SettingData}, System.EventArgs e = {System.EventArgs}) Line 204
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\SettingDataCollection.cs(204)
cs_timed_silver.SettingData.Value.set(object value = true) Line 61
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\SettingData.cs(61)
cs_timed_silver.SettingDataCollection.SetValue(string v = "AutoresizeTableColumns", object value = true) Line 320
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\SettingDataCollection.cs(320)
cs_timed_silver.SettingDataCollection.LoadBoolAttribute(System.Xml.XmlDocument d = {System.Xml.DebuggerDisplayXmlNodeProxy}, string s = "AutoresizeTableColumns") Line 344
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\SettingDataCollection.cs(344)
cs_timed_silver.SettingDataCollection.ImportFromAttributes(System.Xml.XmlDocument doc = {System.Xml.DebuggerDisplayXmlNodeProxy}) Line 450
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\SettingDataCollection.cs(450)
cs_timed_silver.DataFile.LoadFromString(string xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?>...") Line 511
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\DataFile.cs(511)
cs_timed_silver.DataFile.LoadFromFile(string filePath = "C:\\...\\test.xml") Line 753
    at E:\Lucru\cs-timed-silver\cs-timeout\Models\DataFile.cs(753)
cs_timed_silver.MainForm.LoadLastOpenFile() Line 2226
    at E:\Lucru\cs-timed-silver\cs-timeout\Views\MainForm.cs(2226)
cs_timed_silver.MainForm.MainForm_Load(object sender = {cs_timed_silver.MainForm}, System.EventArgs e = {System.EventArgs}) Line 2177

Метод таков:

internal void Cms_ResizeColumnsToFill(object sender, EventArgs e)
{
    if (MyFillColumnsItem.Checked)
    {
        for (int i = 0; i < Columns.Count; ++i)
        {
            Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }
        Columns[(int)TimerColumns.Tag].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

        for (int i = 0; i < Columns.Count; ++i)
        {
            DataGridViewColumn col = Columns[i];
        }
    }
    else
    {
        for (int i = 0; i < Columns.Count; ++i)
        {
            Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
        }
    }

    MyDataFile.SetValue("AutoresizeTableColumns", MyFillColumnsItem.Checked);
}

Я ожидал, что DataError событие не сработало. Фактический результат заключается в том, что произошло событие DataError. Программа работает не очень хорошо, даже если я обрабатываю событие DataError, не показывая ничего: при вводе нового значения в ComboBox оно создается в модели и отображается как выбранное в ComboBox, но когда я выбираю выходящее значение (включая одно соответствующее значение установлено на пустую строку) ComboBox показывает, как будто я ничего не делал, после закрытия его раскрывающегося списка.

1 Ответ

0 голосов
/ 27 марта 2019

Это была старая проблема.В программе есть пользовательский параметр, который заставляет представление сетки данных иметь все столбцы в режиме Fill или все столбцы, имеющие столько ширины, сколько им нужно (AllCells).Когда пользователь изменил этот параметр, это вызвало метод приложения настройки, который также изменил флажок этого параметра.Эта рекурсивность так сильно блокировала сетку данных, что один из столбцов, который был столбцом ComboBox, никогда не загружал свои возможные значения (Items).

Я должен был закомментировать эту строку из кода в вопросе:

MyDataFile.SetValue("AutoresizeTableColumns", MyFillColumnsItem.Checked);

и переместите большую часть кода, связанного с этим параметром, в метод приложения установки MainForm:

case "AutoresizeTableColumns":
    ClockDataGridView cdgv = MyClocksViewProvider.GetExistingOrNewClockDataGridView();
    if (!cdgv.FirstParentChange)
    {
        cdgv.MyFillColumnsItem.Checked =
            (bool)MyDataFile.GetValue("AutoresizeTableColumns");

        if (cdgv.MyFillColumnsItem.Checked)
        {
            for (int i = 0; i < cdgv.Columns.Count; ++i)
            {
                cdgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }
            cdgv.Columns[(int)ClockDataGridView.TimerColumns.Tag].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

            for (int i = 0; i < cdgv.Columns.Count; ++i)
            {
                DataGridViewColumn col = cdgv.Columns[i];
            }
        }
        else
        {
            for (int i = 0; i < cdgv.Columns.Count; ++i)
            {
                cdgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            }
        }
    }
    else
    {
        cdgv.ParentChanged += Cdgv_ParentChanged;
    }
    break;

Наконец:

internal void Cms_ResizeColumnsToFill(object sender, EventArgs e)
{
    MyDataFile.SetValue("AutoresizeTableColumns", MyFillColumnsItem.Checked);
}

и:

private void Cdgv_ParentChanged(object sender, EventArgs e)
{
    ClockDataGridView cdgv = MyClocksViewProvider.GetExistingOrNewClockDataGridView();

    if (cdgv.MyFillColumnsItem.Checked)
    {
        for (int i = 0; i < cdgv.Columns.Count; ++i)
        {
            cdgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }
        cdgv.Columns[(int)ClockDataGridView.TimerColumns.Tag].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

        for (int i = 0; i < cdgv.Columns.Count; ++i)
        {
            DataGridViewColumn col = cdgv.Columns[i];
        }
    }
    else
    {
        for (int i = 0; i < cdgv.Columns.Count; ++i)
        {
            cdgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
        }
    }

    cdgv.ParentChanged -= Cdgv_ParentChanged;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...