如何设置不带DataError异常且上下文为:“ Formatting,PreferredSize”的ParentChanged处理程序中的列的AutoSizeMode?

时间:2019-03-25 06:46:57

标签: c# winforms datagridview

我有一个DataGridView,它有时仅可见。我看到我按以下顺序触发了以下事件:

  1. HandleCreated;
  2. VisibleChanged;
  3. ParentChanged

因此,我将设置所有列以填充表的代码放在ParentChanged处理程序中。但我仍然收到此DataError。

我找不到类似的问题对我有帮助。

我已经开始自己处理DataError,以便查看错误的详细信息。我发现的是:

  • 上下文:Formatting, PreferredSize
  • 列:ComboBox列,接受在Enter菜单中引入的新条目。
  • 消息:“ DataGridViewComboBoxCell无效”。
  • 此列中每一行都有一个非空字符串作为值的消息框。注意:ComboBox列具有一个数据源,该数据源是字符串以外的内容的列表。我将DisplayMemberValueMember以及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 :(得分:0)

这是一个较旧的问题。该程序具有一个用户设置,该设置使数据网格视图在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;
}