【问题标题】:Changing seemingly unrelated code breaks combo box. Causes it to display object name instead of list of values更改看似无关的代码会破坏组合框。使其显示对象名称而不是值列表
【发布时间】:2017-07-18 15:04:30
【问题描述】:

我有一个 C#.net winforms 应用程序,它首先使用实体​​框架代码连接到 SQL DB。

我的一个组合框丢失了它应该从枚举中提取的值列表(12 个月的列表),它只显示月份列表对象的名称。

发生这种情况是因为我更改了与组合完全无关且不应影响它的代码(将一些不相关的代码移至另一个类),并且似乎导致了上述问题。以前当我添加一些新代码时发生了类似的事情,它导致同样的事情发生。最终,在我更改 linq 查询以在某个值为空时返回“TBC”字符串后,它自行修复。请记住,更改的代码与相关组合框无关。在任何不相关的代码运行之前,也会填充组合。

这是填充组合的代码:

private void UpdateMonthCombo()
{
    ArrayList AL = new ArrayList();
    foreach (string cs in Enum.GetNames(typeof(MonthsEnum)))
    {
        MonthList aEnum = new MonthList((int) Enum.Parse(typeof(MonthsEnum), cs), cs);
        AL.Add(aEnum);
    }

    BindingSource source = new BindingSource();
    source.DataSource = AL;
    comboMonth.ValueMember = "_MonthNumber";
    comboMonth.DisplayMember = "_Name";
    comboMonth.DataSource = source;
    comboMonth.SelectedItem = null;
}

我很想知道这种情况是如何发生的,以及如何解决和预防它。我相信你可以说我对 C# 比较陌生!

非常感谢任何帮助。

这是 MonthList 类:

public class MonthList
{

    public string _Name { get; set; }
    public int _MonthNumber { get; set; }

    public MonthList(int MonthNumber, string Name)
    {
        _Name = Name;
        _MonthNumber = MonthNumber;
    }
    public enum MonthsEnum : int
    {
        January = 1,
        February = 2,
        March = 3,
        April = 4,
        May = 5,
        June = 6,
        July = 7,
        August = 8,
        September = 9,
        October = 10,
        November = 11,
        December = 12
    }       
}

尝试使用 this 而不是枚举。在单独的表单上测试按预期工作。但在我的表单上它只显示月份数字:

private void UpdateMonthCombo()
    {
        var monthList = CultureInfo.InvariantCulture.DateTimeFormat.MonthNames.Select((item, index) => new
        {
            Month = item,
            Value = index + 1
        });

        var result = monthList.Where(m => m.Month != "");

        comboMonth.DataSource = result.ToList();
        comboMonth.ValueMember = "Value";
        comboMonth.DisplayMember = "Month";
    }

我重构了组合框上的 selectedindexchanged 事件。它修复了组合框。但现在主网格视图坏了。它似乎与添加组合框列的方法有关。当我注释掉这个方法时,gridview 会显示所有列(没有组合列),但原来的 comboMonth 再次损坏,只显示月份数字:

private void AddProjectCombo()
    {
        gridBusinessKMs.Columns["Project"].Visible = false;
        DataGridViewComboBoxColumn cmbCol = new DataGridViewComboBoxColumn();

        cmbCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
        cmbCol.HeaderText = "Project";
        cmbCol.Name = "Project ";
        cmbCol.Items.Add("True");

        using (var context = new MileageLogDBContext())
        {
            cmbCol.DataSource = (from p in context.Projects
                                 orderby p.ProjectDescription
                                 select p.ProjectDescription).ToList();
        }
        gridBusinessKMs.Columns.Add(cmbCol);
        gridBusinessKMs.Columns["Project "].DisplayIndex = 1;
    }

【问题讨论】:

  • 你能添加一些我们可以检查的代码吗,看起来类对象正在与组合而不是类的属性/成员绑定
  • 一些特定的代码有助于了解发生了什么。
  • comboMonth.DataSource = 源;这不是数据源对象的名字吗?
  • 我已更改为 comboMonth.DataSource = AL;但问题仍然存在。
  • 我试过这个:private void UpdateMonthCombo() { var monthList = CultureInfo.InvariantCulture.DateTimeFormat.MonthNames.Select((item, index) => new { Month = item, Value = index + 1 }); var result = monthList.Where(m => m.Month != ""); comboMonth.DataSource = result.ToList(); comboMonth.ValueMember = "Value"; comboMonth.DisplayMember = "Month"; } ...它适用于单独的表单,但当添加到我的原始表单时,它只显示组合中的数字

标签: c# winforms combobox


【解决方案1】:

我相信 ArrayList 包含对对象的引用,您可能会更改对象并因此更改绑定源。 (请参阅此问题的答案:ArrayList vs List<> in C#)如果绑定源已更改,则 DisplayMember 的值可能会恢复为对象的 ToString 方法:

如果指定的属性在对象上不存在,或者 DisplayMember 的值为空字符串 (""),则显示对象的 ToString 方法的结果。

https://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.displaymember(v=vs.110).aspx

我不知道 MonthsEnumMonthList 在做什么,但我测试了以下代码并且它有效。

private void UpdateMonthCombo()
    {
        List<Tuple<int, string>> AL = new List<Tuple<int, string>>();

        string[] monthNames = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;

        for (int i = 0; i < 12; i++)
        {
            AL.Add(new Tuple<int, string>(i + 1, monthNames[i]));
        }

        comboMonth.DataSource = AL;
        comboMonth.ValueMember = "Item1";
        comboMonth.DisplayMember = "Item2";
        comboMonth.SelectedItem = null;
    }

【讨论】:

  • 这导致了一些错误(类似于“在此上下文中仅支持原始类型或枚举类型。”),我使用 LINQ 查询来填充一些网格。我修改了它们并打开了表单,但 comboMonth 只显示了从 1 到 12 的数字,而不是月份名称。
  • @Salbrox 看起来,如果您的代码以另一种形式工作,那么该错误将保留在您的原始形式中,而不是您正在工作的代码中。我怀疑您的代码正在修改组合框的某些部分,并且显示成员正在恢复为 ToString() 方法。 (如果您注释掉 comboMonth.DisplayMember = "Item2"; 行,那么组合框将恢复为仅当月的数字。)
  • 我似乎已经通过重构组合框的 SelectedIndexChanged 事件修复了组合框。我不知道为什么或如何影响组合的 DisplayMember,但确实如此。但现在我的网格视图坏了!它只显示一列。我有一个方法,它添加了一个带有组合框的列。当我将其注释掉时,gridview 会显示所有列,但原始组合框仅返回数字!现在对这一切感到非常困惑。
  • @Salbrox 听起来像个谜。如果您想发布其他代码 sn-ps 我有兴趣寻找错误。
  • 我设法修复了它。我不明白为什么。我有一个方法可以提取当前选定的月份并将其作为参数传递给另一个返回值的方法。该方法正在从全局变量中查找值,但也被设置为接受与参数相同的值。我更改了代码,以便它接受参数并且它工作。我不明白这会如何影响提供参数的组合框的显示成员。无论如何它现在工作正常。
猜你喜欢
  • 2016-07-21
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多