C# 一个数据源只需要多个BindingSource组件?

C# 一个数据源只需要多个BindingSource组件?,c#,data-binding,bindingsource,icustomtypedescriptor,C#,Data Binding,Bindingsource,Icustomtypedescriptor,根据我的上一个问题,我管理了表单,通过实现接口,我可以为表单设计器提供自定义属性,这些属性可能在相关组件上作为真实的普通属性可见,也可能不可见 我做到了这一点,但我的实现有缺陷。我现在遇到的最大问题是,如果我在表单上删除一个组件(它有两个这样的自定义属性),然后在表单上删除两个文本框,并使用数据绑定,那么属性检查器中的数据绑定下拉列表需要一个对象数据源,但是绑定到控件的每个属性都会在表单上添加另一个组件 让我换一种说法。我将自定义组件放到表单上。它有两个属性,可通过我的实现使用,但不作为普通属性

根据我的上一个问题,我管理了表单,通过实现接口,我可以为表单设计器提供自定义属性,这些属性可能在相关组件上作为真实的普通属性可见,也可能不可见

我做到了这一点,但我的实现有缺陷。我现在遇到的最大问题是,如果我在表单上删除一个组件(它有两个这样的自定义属性),然后在表单上删除两个文本框,并使用数据绑定,那么属性检查器中的数据绑定下拉列表需要一个对象数据源,但是绑定到控件的每个属性都会在表单上添加另一个组件

让我换一种说法。我将自定义组件放到表单上。它有两个属性,可通过我的实现使用,但不作为普通属性可见

然后我在表单上放置两个文本框。我去属性检查器为其中一个属性添加文本属性的数据绑定,它需要项目中的一个对象数据源,我添加了它。然后,在将textbox上的Text属性绑定到我的自定义组件的第一个属性之后,表单设计器添加了另一个组件,即“customDataBindingBindingSource”,用于在两者之间桥接数据绑定。到目前为止,一切顺利

然后,当我以同样的方式为另一个文本框设置数据绑定时(除了我现在可以选择自定义组件的另一个属性),会添加另一个这样的桥,“customDataBindingBindingSource1”。如果我一直切换要绑定的属性,那么每次都会添加一个这样的桥

这真的有必要吗

如果没有,我在实现中做错了什么?诚然,这是幼稚和简单的,远未完成,但我不知道我需要修复什么。有什么建议吗

这是我的自定义类:

public class CustomDataBinding : Component, ICustomTypeDescriptor, INotifyPropertyChanged
{
    private String _Property1;
    private String _Property2;

    public class MyPropertyDescriptor : PropertyDescriptor
    {
        private String _Name;

        public MyPropertyDescriptor(String name)
            : base(name, null)
        {
            _Name = name;
        }

        public override bool CanResetValue(object component)
        {
            return true;
        }

        public override Type ComponentType
        {
            get { return typeof(CustomDataBinding); }
        }

        public override object GetValue(object component)
        {
            CustomDataBinding source = (CustomDataBinding)component;
            switch (_Name)
            {
                case "Property1":
                    return source._Property1;
                    break;

                case "Property2":
                    return source._Property2;
                    break;

                default:
                    return null;
            }
        }

        public override bool IsReadOnly
        {
            get { return false; }
        }

        public override Type PropertyType
        {
            get { return typeof(String); }
        }

        public override void ResetValue(object component)
        {
            SetValue(component, _Name);
        }

        public override void SetValue(object component, object value)
        {
            CustomDataBinding source = (CustomDataBinding)component;
            switch (_Name)
            {
                case "Property1":
                    source._Property1 = Convert.ToString(value);
                    Debug.WriteLine("Property1 changed to " + value);
                    break;

                case "Property2":
                    source._Property2 = Convert.ToString(value);
                    Debug.WriteLine("Property2 changed to " + value);
                    break;

                default:
                    return;
            }
            source.OnPropertyChanged(_Name);
        }

        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
    }

    public CustomDataBinding()
    {
        _Property1 = "Property1";
        _Property2 = "Property2";
    }

    #region ICustomTypeDescriptor Members

    public AttributeCollection GetAttributes()
    {
        return new AttributeCollection(null);
    }

    public string GetClassName()
    {
        return null;
    }

    public string GetComponentName()
    {
        return null;
    }

    public TypeConverter GetConverter()
    {
        return null;
    }

    public EventDescriptor GetDefaultEvent()
    {
        return null;
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return null;
    }

    public object GetEditor(Type editorBaseType)
    {
        return null;
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return new EventDescriptorCollection(null);
    }

    public EventDescriptorCollection GetEvents()
    {
        return new EventDescriptorCollection(null);
    }

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        return new PropertyDescriptorCollection(new PropertyDescriptor[] {
            new MyPropertyDescriptor("Property1"),
            new MyPropertyDescriptor("Property2") });
    }

    public PropertyDescriptorCollection GetProperties()
    {
        return GetProperties(null);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(String name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }

    public void SetValues(String p1, String p2)
    {
        _Property1 = p1;
        _Property2 = p2;

        OnPropertyChanged("Property1");
        OnPropertyChanged("Property2");
    }

    #endregion
}
此外,我需要手动将这些网桥连接到我最初在表单构造函数中丢弃的组件,如下所示:

customDataBindingBindingSource.DataSource = customDataBinding1;
customDataBindingBindingSource1.DataSource = customDataBinding1;
有没有办法避免很多这样的事情

基本上,当使用我的组件时,我想做的是:

  • 将一个自定义组件拖放到窗体上
  • 删除必要的控件(文本框、日期选择器等)
  • 将控件的数据绑定指定给自定义组件上的相关属性
  • 如果可能,我希望避免在构造函数中包含项目数据源、桥接组件以及代码。所有我想避免的事情


    请注意,我没有要求任何人给我这些代码。欢迎任何指点。

    这是IDE工作吗?在IDE中使用时,它主要是PropertyGrid;我(在最后一个问题上)添加了一个使用TypeConverter简化事情的示例。。。我还没有读完整的问题(上面),但很快就会(忙)。是的,我使用Visual Studio 2008,当我说“drop”时,基本上是指在重建项目后,我将自定义组件从工具箱中放到表单设计器中。问题基本上是从表单设计师那里得到帮助,用尽可能少的手动代码为我设置一切。嗨,你解决了这个问题吗?我尝试过与您非常相似的方法,并且似乎记得在组件托盘中看到了大量CustomBindingSources。不过,我还有一个困难。当我运行应用程序时,收到异常:“无法绑定到数据源上的属性或列。”。参数名称:dataMember'。尽管存在多个BindingSources的问题,但您的应用程序实际运行了吗?不幸的是,还没有,但项目的这一部分暂时还不需要,因此我们推迟了问题的解决。不过我很快就会谈到。嗨@LasseV.Karlsen你有没有实现过这个?