为什么可浏览属性使财产不能绑定? [英] Why Browsable attribute makes property not bindable?

查看:150
本文介绍了为什么可浏览属性使财产不能绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用 System.Windows.Forms.PropertyGrid

为使属性不在此网格应该使用可见的 BrowsableAttribute 设置为
,而加入这个属性使得属性不绑定

To make a property not visible in this grid one should use BrowsableAttribute set to false. But adding this attribute makes the property not bindable.

示例:创建新的Windows窗体项目,并掉落文本框的PropertyGrid Form1中。使用下面的代码中,文本框的宽度不会被绑定到 Data.Width

Example: Create a new Windows Forms project, and drop a TextBox and PropertyGrid onto Form1. Using the code below, the width of the TextBox does not get bound to Data.Width:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Data data = new Data();
        data.Text = "qwe";
        data.Width = 500;

        BindingSource bindingSource = new BindingSource();
        bindingSource.Add(data);

        textBox1.DataBindings.Add("Text", bindingSource, "Text", true,
            DataSourceUpdateMode.OnPropertyChanged);
        textBox1.DataBindings.Add("Width", bindingSource, "Width", true,
            DataSourceUpdateMode.OnPropertyChanged);

        propertyGrid1.SelectedObject = data;
    }
}

有关数据类的代码是:

public class Data : IBindableComponent
{
    public event EventHandler TextChanged;
    private string _Text;
    [Browsable(true)]
    public string Text
    {
        get
        {
            return _Text;
        }
        set
        {
            _Text = value;
            if (TextChanged != null)
                TextChanged(this, EventArgs.Empty);
        }
    }

    public event EventHandler WidthChanged;
    private int _Width;
    [Browsable(false)]
    public int Width
    {
        get
        {
            return _Width;
        }
        set
        {
            _Width = value;
            if (WidthChanged != null)
                WidthChanged(this, EventArgs.Empty);
        }
    }

    #region IBindableComponent Members

    private BindingContext _BindingContext;
    public BindingContext BindingContext
    {
        get
        {
            if (_BindingContext == null)
                _BindingContext = new BindingContext();

            return _BindingContext;
        }
        set
        {
            _BindingContext = value;
        }
    }

    private ControlBindingsCollection _DataBindings;
    public ControlBindingsCollection DataBindings
    {
        get 
        {
            if (_DataBindings == null)
                _DataBindings = new ControlBindingsCollection(this);

            return _DataBindings;    
        }
    }

    #endregion

    #region IComponent Members

    public event EventHandler Disposed;

    public System.ComponentModel.ISite Site
    {
        get
        {
            return null;
        }
        set
        {

        }
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    #endregion
}

如果您切换可浏览属性设置为true的每个数据它的工作性能。
现在好像BindingSource的搜索由可浏览属性数据源

If you switch the Browsable attribute to true on every property in Data it works. Now it seems like BindingSource searches datasource by Browsable Attribute.

推荐答案

基于更新例如更新的答案:

我已经做了在反射一些挖掘,发现了问题,实际上是在 ListBindingHelper ,这是由的CurrencyManager ,后者又由的BindingSource (这些都是在<$使用C $ C> System.Windows.Forms的命名空间)。

I've done some digging in Reflector and discovered that the "problem" is actually in ListBindingHelper, which is used by CurrencyManager, which is in turn used by the BindingSource (these are all in the System.Windows.Forms namespace).

要发现可绑定属性,的CurrencyManager 调用 ListBindingSource.GetListItemProperties 。引擎盖下,这个召唤出 GetListItemPropertiesByInstance (当你在一个单一的对象传递)。这种方法的代码在末尾以下行:

To discover the bindable properties, the CurrencyManager invokes ListBindingSource.GetListItemProperties. Under the hood, this calls out to GetListItemPropertiesByInstance (when you pass in a single object). That method has the following line of code at the end:

return TypeDescriptor.GetProperties(target, BrowsableAttributeList);

BrowsableAttributeList 的实施

private static Attribute[] BrowsableAttributeList
{
    get
    {
        if (browsableAttribute == null)
        {
            browsableAttribute = new Attribute[] { new BrowsableAttribute(true) };
        }
        return browsableAttribute;
    }
}

您可以看到它,实际上,过滤通过 BrowsableAttribute属性(真)。这或许应该使用 BindableAttribute 代替,但我的猜测是,设计者意识到,每个人都已经根据 BrowsableAttribute 和决定使用一个替代。

You can see that it is, in fact, filtering properties by BrowsableAttribute(true). It should probably be using BindableAttribute instead, but my guess is that the designers realized that everybody was already depending on BrowsableAttribute and decided to use that one instead.

所以,很遗憾,你将无法来解决这个问题,如果你使用 BrowsableAttribute 。你唯一的选择是要么做什么马克提出和使用自定义的TypeConverter 或过滤器本身使用这一问题的解决方案之一属性网格:的编程方式隐藏场PropertyGrid中

So unfortunately you won't be able to get around this issue if you use BrowsableAttribute. Your only options are to either do what Marc suggests and use a custom TypeConverter, or filter the property grid itself using one of the solutions in this question: Programatically Hide Field in PropertyGrid.

这篇关于为什么可浏览属性使财产不能绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆