简体   繁体   English

C#WinForms中的动态组合框列表数据绑定

[英]Dynamic combobox list databinding in C# WinForms

Have read a lot this resource and really like it, but now i met problem which i can't neither resolve by myself nor find similar solution. 已经阅读了很多该资源并且非常喜欢它,但是现在我遇到了一个问题,既不能自己解决也不能找到类似的解决方案。 I'm using C# winforms and linqtosql. 我正在使用C#winforms和linqtosql。 In my userforms I use additional view-class to bind list for comboboxes to let users be able to get and use a name-list of objects while being forbidden to get a whole object itself. 在我的用户窗体中,我使用其他视图类绑定组合框列表,以使用户能够获取和使用对象的名称列表,同时禁止获取整个对象本身。 (This is not question whether it is a good practice, no matter.) (无论如何,这不是一个好习惯的问题。)

For example(this is not real code, just for look): ORM classes: 例如(这不是真正的代码,仅用于查看):ORM类:

public class Contract
{
    public string ID { get; set; }
    public string Name { get; set; }
    public Contractor Contractor { get; set; }
    public string ContractorID { get; set; }
}
public class Contractor
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
}

This is additional view-class which is mapping for sqlserver view Contractor_List (SELECT c.ID, c.Name FROM Contractors c) 这是为sqlserver视图Contractor_List映射的附加视图类(SELECT c.ID, c.Name FROM Contractors c)

public class Contractor_List
{
    public string ID { get; set; }
    public string Name { get; set; }
}

UserForm: 用户表格:

public class ContractForm : Form
{
    void Init()
    {
        TextBox nameBox = new TextBox();
        ComboBox contractorBox = new ComboBox();
        BindingSource contractSource = new BindingSource();
        contractSource.DataSource = typeof (Contract);

        nameBox.DataBindings.Add("Text", contractSource, "Name", false, DataSourceUpdateMode.OnValidation);
        contractorBox.DataBindings.Add("SelectedValue", contractSource, "ContractorID", false, DataSourceUpdateMode.OnValidation);


        BindingSource contractorListSource = new BindingSource();
        contractorListSource.DataSource = typeof (Contractor_List);

        contractorBox.DisplayMember = "Name";
        contractorBox.ValueMember = "ID";
    }

}

OK. 好。 My idea is to load contractorBox.DataSource (it's binding source) when contractorBox.SelectedValue is set. 我的想法是在设置contractorBox.SelectedValue时加载contractorBox.DataSource(它的绑定源)。 I found that SelectedValue is not overridable, so I decided to inherit combobox and to create in it a new property called “ID” and do following stuff instead In form: 我发现SelectedValue不可覆盖,因此我决定继承combobox,并在其中创建一个名为“ ID”的新属性,并按照以下格式进行操作:

contractorBox.DataBindings.Add("ID", contractSource, "ContractorID");

In Control (this is real code): 在控制中(这是真实的代码):

    object _id;
    bool _listInitialized;
    public object ID
            {
                get
                {
                    return _id;

                }
                set
                {
                    if (!_listInitialized)
                    {
                        var bindingSource = DataSource as BindingSource;
                        if (bindingSource != null)
                        {
                            var t = (bindingSource.DataSource as Type);
                            var rst = … //Getting List
                            if (rst!=null)
                            {
                                bindingSource.DataSource = rst;
                                _listInitialized = true;
                                SelectedValueChanged += delegate {
                                    if (SelectedValue != ID)
                                    {
                                        ID = SelectedValue;
                                    }
                                };
                            }
                        }
                    }
                    else
                    {
                        _id = value;
                        if (SelectedValue != ID)
                        {
                            SelectedValue = value;
                        }
                    }

                }
            }

So, this code works fine. 因此,此代码可以正常工作。 I can load form, Contract object and list of contractors and get right contractor name in combobox. 我可以加载表单,合同对象和承包商列表,并在组合框中获取正确的承包商名称。 But. 但。 I have problem with backing Binding of “ID” property. 我在支持“ ID”属性的绑定时遇到问题。 When contractor in combobox is changed Contract object doesn't update (neither ContractorID , no Contractor Itself) while ID , SelectedValue and SelectedItem of combobox change properly. 更改组合框内的承包商时,合同对象不会更新( ContractorID ,也没有Contractor本身),而组合框的IDSelectedValueSelectedItem正确更改。 Why? 为什么? What have I do to make this working. 我要怎么做才能使其正常工作。

Hah. 哈哈 So Simple Solution. 如此简单的解决方案。

public new object SelectedValue
{
    get
    {
        return base.SelectedValue;

    }
    set
    {
        if (!DesignMode)
        {
            if (!_listInitialized)
            {
                var bindingSource = DataSource as BindingSource;
                if (bindingSource != null)
                {
                    var t = (bindingSource.DataSource as Type);
                    var rst = ...///how you get your type list
                    if (rst != null)
                    {
                        bindingSource.DataSource = rst;
                        _listInitialized = true;
                    }
                }
            }
            else
            {
                base.SelectedValue = value;
            }
        }
    }
}

May be will be helpful for someone. 可能会对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM