1

我有一个BindingList< KeyValuePair < string, string > >绑定到ComboBox控件的。根据某些条件,BindingList将添加一个新的KeyValuePair. 现在,新添加的项目显示在 的索引 0 处Combobox,而不是末尾。

在调试时,我发现BindingList得到了正确的顺序。(即KeyValuePair附加新的)

另外,我检查了SelectedValueComboBoxSelectedIndexChanged处理程序,它似乎不是ListItem被选中的。相反,它是假定的ListItem,如果ComboBox得到了正确的顺序,如它的DataSource, - the BindingList..

代码是一个大项目的一小部分。如果问题不清楚,请告诉我。我可以根据我们的上下文放置代码的相关部分。

怎么会发生这样的事情?我能做些什么不同的事情?

我有这样的课程。

public class DropdownEntity
{
    //removed all except one members and properties

    private string frontEndName
    public string FrontEndName
    {
        get {return this.frontEndName; }
        set {this.frontEndName= value; }
    }

    //One Constructor
    public DropdownEntity(string _frontEndName)
    {
        this.FrontEndName = _frontEndName;

        //Removed code which initializes several members...
    }

    //All methods removed..

    public override string ToString()
    {
        return frontEndName;
    }
}

在我的 Windows 窗体中,我有一个带有多个选项卡的选项卡控件。在其中一个标签页中,我有一个 DataGridView。用户应该编辑单元格并单击 Next - 按钮。然后,将进行一些处理,并将 TabControl 导航到下一个标签页。

下一个标签页有我提到的问题的组合框。这个页面还有一个返回按钮,它会收回。用户可以再次修改gridview单元格。然后点击下一步按钮。这是订单混乱的时候。

我在这里发布了 Next Button 的 Click 事件处理程序。与类一起,删除了其余代码。

public partial class AddUpdateWizard : Form
{        
    //Removed all members..

    BindingList<KeyValuePair<string, string>> DropdownsCollection;
    Dictionary<string, DropdownEntity> DropdownsDict;

    //Defined in a partial definition of the class..
    DataGridView SPInsertGridView = new DataGridView();
    ComboBox DropdownsCmbBox = new ComboBox();

    Button NextBtn2 = new Button();
    Button BackBtn3 = new Button();
    //Of course these controls are added to one of the panels

    public AddUpdateWizard(MainForm mainForm)
    {
        InitializeComponent();
        DropdownsDict = new Dictionary<string, DropdownEntity>();
    }

    private void NextBtn2_Click(object sender, EventArgs e)
    {
        string sqlArgName;
        string frontEndName;
        string fieldType;

        for (int i = 0; i < SPInsertGridView.Rows.Count; i++)
        {
            sqlArgName = "";
            frontEndName = "";
            fieldType = "";

            sqlArgName = SPInsertGridView.Rows[i].Cells["InsertArgName"].Value.ToString().Trim();

            if (SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value != null)
            {
                frontEndName = SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value.ToString().Trim();
            }

            if (SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value != null)
            {
                fieldType = SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value.ToString().Trim();
            }

            //I could have used an enum here, but this is better.. for many reasons.
            if (fieldType == "DROPDOWN")
            {
                if (!DropdownsDict.ContainsKey(sqlArgName))
                    DropdownsDict.Add(sqlArgName, new DropdownEntity(frontEndName));
                else
                    DropdownsDict[sqlArgName].FrontEndName = frontEndName;
            }
            else
            {
                if (fieldType == "NONE")
                    nonFieldCount++;

                if (DropdownsDict.ContainsKey(sqlArgName))
                {
                    DropdownsDict.Remove(sqlArgName);
                }
            }

        }

        //DropdownsCollection is a BindingList<KeyValuePair<string, string>>.
        //key in the BindingList KeyValuePair will be that of the dictionary.
        //The value will be from the ToString() function of the object in the Dictionary. 

        DropdownsCollection = new BindingList<KeyValuePair<string,string>>(DropdownsDict.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString())).ToList());

        DropdownsCmbBox.DataSource = DropdownsCollection;

        DropdownsCmbBox.DisplayMember = "Value";
        DropdownsCmbBox.ValueMember = "Key";            

        //Go to the next tab
        hiddenVirtualTabs1.SelectedIndex++;
    }

    private void BackBtn3_Click(object sender, EventArgs e)
    {
        hiddenVirtualTabs1.SelectedIndex--;
    }

    //On Selected Index Changed of the mentioned Combobox..        
    private void DropdownsCmbBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (DropdownsCmbBox.SelectedValue != null)
        {
            if (DropdownsDict.ContainsKey((DropdownsCmbBox.SelectedValue.ToString())))
            {
                var dropdownEntity = DropdownsDict[DropdownsCmbBox.SelectedValue.ToString()];

                DropdownEntityGB.Text = "Populate Dropdowns - " + dropdownEntity.ToString();

                //Rest of the code here..
                //I see that the Datasource of this ComboBox has got the items in the right order.
                // The Combobox's SelectedValue is not that of the selected item. Very Strange behavior!!

            }
        }
    }
}

用户第一次单击“下一步”按钮时,一切正常。但如果他再次单击后退按钮并更改数据网格视图单元格.. 订单将消失。

我知道,看起来可能会令人沮丧。寻求帮助是一件大事。任何帮助将不胜感激!

如果您需要详细说明,请告诉我。

非常感谢 :)

4

2 回答 2

1

我认为你在这里有两个问题。

首先,如果您想保留项目的顺序,您应该使用OrderedDictionary而不是常规的。使用 Remove 方法时,普通集合不会保留项目的顺序。您可以在此处查看与 List 相关的更多信息。

你可以像这样使用这样的字典:

DropDownDict = new OrderedDictionary();
// Add method will work as expected (as you have it now)

// Below you have to cast it before using Select
DropDownCollection = new BindingList<KeyValuePair<string, string>>(DropDownDict.Cast<DictionaryEntry>().Select(kvp => new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())).ToList());

第二个问题可能是您更改了现有项目的显示名称 (FrontEndName),但保留了密钥。添加新项目时,请尝试删除不再使用的旧项目并添加新项目。

于 2013-06-10T08:50:23.010 回答
1

组合框的 Sorted 属性设置为 True!直到现在我才检查。我搞砸了。非常抱歉浪费您的时间阿德里安。非常感谢您在这里忍受我的烂摊子.. :)

于 2013-06-10T13:35:00.160 回答