当前位置:编程学习 > C#/ASP.NET >>

一个关于PropertyGrid的问题,网上怎么都找不到答案,高人指点。

我做一个基于设计器IDesignerHost的程序,我想让DesignSu易做图ce.View上的控件在PropertyGrid中显示的属性为中文,于是我实现了ICustomTypeDescriptor接口MyCustomTypeDescriptor,但是有一个问题确实怎么也解决不了,那就是在属性中没有Name名字这一项,我查看了控件的基类Control,发现Name被定义为<Browsable(False)>,我在MyCustomTypeDescriptor中来修改Name的Browsable特性,可是结果还是一样。我发现除了把设计器中的控件直接传给PropertyGrid.SelectedObject以外,其他像把MyCustomTypeDescriptor实例或是在运行模式中把控件传递给PropertyGrid.SelectedObject,都不会有(Name)这一项,怎么做才能让他显示出来并且让Name可修改?

请高手给予指点,先拜谢! --------------------编程问答-------------------- 自已定义一个字段用来显示中文称,在描述器中,让GRID显示这个字段的值即可,你继承了这个接口,里面有很多方法需要重写 --------------------编程问答-------------------- 参考下面的实现,可以自由展示类的元数据,看起来可以随意改变,其实是做了中间转换.

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Xml;
using Generator.Design.Common;

namespace Generator.Design.BLL
{
    /// <summary>
    /// 实现属性到PropertyGrid重现的重要类,必须根据实际需要来呈现
    /// </summary>
    public class PropertyBaseDescriptor:PropertyDescriptor
    {
        private Attribute[] m_attributes;
        private PropertyBase m_pd;
        private XmlDocument xmldoc = new XmlDocument();

        public PropertyBaseDescriptor(PropertyBase t_pd, Attribute[] t_attributes)
            : base(t_pd.Name, t_attributes)
        {
            m_pd = t_pd;
            m_attributes = t_attributes;
        }
        

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

        public override object GetValue(object component)
        {
            return m_pd.Value;
        }

        public override void ResetValue(object component)
        {
            
        }
        
        public override void SetValue(object component, object value)
        {
            m_pd.Value = value;
        }
        //重要属性,用来显示中文名称或自定义的值,我把中文名称放在一个XML文件里
        public override string DisplayName
        {
            get
            {
                string t_name = m_pd.Name.Trim();
                
                string t_path = Utility.GetRootPath() + "\\Config\\ChineseName.xml";
                xmldoc.Load(t_path);
                XmlNode node=null;
                try
                {
                    node = xmldoc.SelectSingleNode(string.Format("/NameList//NameString[@name=\"{0}\"]", t_name));
                }
                catch
                {
                    node = null;
                }
                if (node != null)
                {
                    t_name = node.InnerText;
                }
                return t_name ;
            }
        }

        public override string Category
        {
            get
            {
                return m_pd.Category;
            }
        }

        public override Type ComponentType
        {
            get { return m_pd.GetType(); }
        }
        public override bool IsReadOnly
        {
            get { return m_pd.IsReadOnly; }
        }
        public override Type PropertyType
        {
            get
            {
                if (m_pd.Value != null)
                {
                    return m_pd.Value.GetType();
                }
                else
                {
                    //有可能有问题,也就是说,如果值为空,将不能获取对象的属性类型
                    //不知有没有别的方法
                    return typeof(string);
                }
            }
        }

        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
        public override bool IsBrowsable
        {
            get
            {
                return m_pd.IsBrowsable;
            }
        }

        public override TypeConverter Converter
        {
            get
            {
                return m_pd.Converter;
            }
        }
        public override object GetEditor(Type editorBaseType)
        {
            return m_pd.uiTypeConvertor;
        }
    }
}
--------------------编程问答-------------------- 下面的代码有二个作用,一是定义属性基类,二是定义属性基类集合,因为PROPERTYGRID显示的是属性类集合.
下面的方法中可以自由定义属性的显示与隐瞒,可以达到根据某个属性的值来决定是否显示其它属性的效果,包括只读或可写.


using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.Drawing.Design;

namespace Generator.Design.BLL
{
    /// <summary>
    /// 对应类的一个属性,尽可能包括类属性所有的特点
    /// </summary>
    public class PropertyBase
    {
        private string m_Name;
        private object m_Value;
        private string m_Description;
        private string m_Category;
        private bool m_isReadOnly;
        private bool m_IsBrowsable;
        private Type m_type;
        private TypeConverter m_Converter;
        private UITypeEditor m_uiTypeEditor;

        private List<Attribute> m_attrs=new List<Attribute>();

        /// <summary>
        /// 属性名
        /// </summary>
        public string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                m_Name = value;
            }
        }
        /// <summary>
        /// 属性值
        /// </summary>
        public object Value
        {
            get
            {
                return m_Value;
            }
            set
            {
                m_Value = value;
            }
        }
        /// <summary>
        /// 属性描述
        /// </summary>
        public string Description
        {
            get
            {
                return m_Description;
            }
            set
            {
                m_Description = value;
            }
        }
        /// <summary>
        /// 属性的特性
        /// </summary>
        public Attribute[] Attributes
        {
            get
            {
                Attribute[] t_atts = new Attribute[m_attrs.Count];
                int iCount = m_attrs.Count;
                for (int j = 0; j < iCount; j++)
                {
                    t_atts[j] = m_attrs[j];
                }
                return t_atts;
            }
        }
        /// <summary>
        /// 属性所属分类
        /// </summary>
        public string Category
        {
            get
            {
                return m_Category;
            }
            set
            {
                m_Category = value;
            }
        }
        /// <summary>
        /// 是否只读
        /// </summary>
        public bool IsReadOnly
        {
            get
            {
                return m_isReadOnly;
            }
            set
            {
                m_isReadOnly = value;
            }
        }
        /// <summary>
        /// 是否显示
        /// </summary>
        public bool IsBrowsable
        {
            get
            {
               
                return m_IsBrowsable;
            }
            set
            {
                m_IsBrowsable = value;
            }
        }
        /// <summary>
        /// 属性类型
        /// </summary>
        public Type PropertyType
        {
            get
            {
                return m_type;
            }
            set
            {
                m_type = value;
            }
        }
        /// <summary>
        /// 属性的类型转换器
        /// </summary>
        public TypeConverter Converter
        {
            get
            {
                return m_Converter;
            }
            set
            {
                m_Converter = value;
            }
        }
        /// <summary>
        /// 属性指定的UI编辑器
        /// </summary>
        public UITypeEditor uiTypeConvertor
        {
            get
            {
                return m_uiTypeEditor;
            }
            set
            {
                m_uiTypeEditor = value;
            }
        }
        /// <summary>
        /// 给属性增加一个特性
        /// </summary>
        /// <param name="t_newatt"></param>
        public void AddAttribute(Attribute t_newatt)
        {
            if (m_attrs.Count > 0)
            {
                foreach (Attribute t_att in m_attrs)
                {
                    if (t_att.Match(t_newatt))
                    {
                        m_attrs.Remove(t_att);
                    }
                }
            }
            m_attrs.Add(t_newatt);
        }
        /// <summary>
        /// 删除属性的一个特性
        /// </summary>
        /// <param name="t_att"></param>
        public void DeleteAttribute(Attribute t_att)
        {
            try
            {
                m_attrs.Remove(t_att);
            }
            catch { }
        }
    }
     --------------------编程问答-------------------- /// <summary>
    /// 对应类的所有属性,相当于上上一个类的集合,提供给PropertyGrid来显示
    /// 因为是定制的,必须实现定制接口
    /// </summary>
    public class PropertyBaseCollection :ICustomTypeDescriptor
    {
        #region 实现功能(基于List<PropertyBase>)
        /// <summary>
        /// 类属性泛型集合变量
        /// </summary>
        private List<PropertyBase> m_propertys=new List<PropertyBase>();
        /// <summary>
        /// 新增一个属性
        /// </summary>
        /// <param name="t_property">属性类</param>
        public void Add(PropertyBase t_property)
        {
            m_propertys.Add(t_property);
        }
        /// <summary>
        /// 删除一个属性
        /// </summary>
        /// <param name="t_property">属性类</param>
        public void Delete(PropertyBase t_property)
        {
            m_propertys.Remove(t_property);
        }
        /// <summary>
        /// 删除一个属性
        /// </summary>
        /// <param name="t_PropertyName">属性名</param>
        public void Delete(string t_PropertyName)
        {
            int i = m_propertys.Count;
            PropertyBase t;
            for (int j=0;j<i;j++)
            {
                t = m_propertys[j];
                if (t.Name.Trim() == t_PropertyName.Trim())
                {
                    m_propertys.Remove(t);
                    break;
                }
            }
        }
        /// <summary>
        /// 根据属性名,设置只读特性
        /// </summary>
        /// <param name="t_PropertyName">属性名</param>
        /// <param name="t_bl">布尔值</param>
        /// <returns></returns>
        public bool UpdateWriteRead(string t_PropertyName, bool t_bl)
        {
            bool t_ok = false;
            try
            {
                int iCount = m_propertys.Count;
                if (iCount > 0)
                {
                    for (int i = 0; i < iCount; i++)
                    {
                        if (m_propertys[i].Name.Trim() == t_PropertyName.Trim())
                        {
                            m_propertys[i].IsReadOnly = t_bl;
                            t_ok = true;
                            break;
                        }
                    }
                }
                
            }
            catch
            {
                t_ok = false;
            }
            return t_ok;
        }
        /// <summary>
        /// 根据属性名,设置隐藏特性
        /// </summary>
        /// <param name="t_PropertyName">属性名</param>
        /// <param name="t_bl">布尔值</param>
        /// <returns></returns>
        public bool HideProperty(string t_PropertyName, bool t_bl)
        {
            bool t_ok = false;
            try
            {
                int iCount = m_propertys.Count;
                if (iCount > 0)
                {
                    for (int i = 0; i < iCount; i++)
                    {
                        if (m_propertys[i].Name.Trim() == t_PropertyName.Trim())
                        {
                            m_propertys[i].IsBrowsable = t_bl;
                            
                            t_ok = true;
                            break;
                        }
                    }
                }

            }
            catch
            {
                t_ok = false;
            }
            return t_ok;
        }
        /// <summary>
        /// 类属性个数
        /// </summary>
        public int Count
        {
            get
            {
                return m_propertys.Count;
            }
        }
        /// <summary>
        /// 类属性索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public PropertyBase this[int index]
        {
            get
            {
                return m_propertys[index];
            }
        }

        public PropertyBase this[string t_PropertyName]
        {
            get
            {
                PropertyBase t_property = null;
                int iCount = m_propertys.Count;
                for (int i = 0; i < iCount; i++)
                {
                    if (m_propertys[i].Name.Trim().ToLower() == t_PropertyName.Trim().ToLower())
                    {
                        t_property= m_propertys[i];
                        break;
                    }
                }
                return t_property;
            }
        }

        #endregion

        #region 以下部分是实现接口规范
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }
        

        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this,true);
        }
        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }
        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }
        public object GetEditor(Type t_type)
        {
            return TypeDescriptor.GetEditor(this, t_type, true);
        }
        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this,true);
        }
        public EventDescriptorCollection GetEvents(Attribute[] t_attrs)
        {
            return TypeDescriptor.GetEvents(this, t_attrs, true);
        }
        public PropertyDescriptorCollection GetProperties()
        {
            return TypeDescriptor.GetProperties(this, true);
        }
        public PropertyDescriptorCollection GetProperties(Attribute[] t_attrs)
        {
            List<PropertyBase> tmp_props = new List<PropertyBase>();
            foreach (PropertyBase tt in m_propertys)
            {
                if (tt.IsBrowsable)
                {
                    tmp_props.Add(tt);
                }
            }
            PropertyDescriptor[] t_props = new PropertyBaseDescriptor[tmp_props.Count];
            int i = -1;
            
            foreach (PropertyBase tt in tmp_props)
            {
               
                    i++;
                    t_props[i] = new PropertyBaseDescriptor(tmp_props[i], null);
            }

            return new PropertyDescriptorCollection(t_props);
        }
        public object GetPropertyOwner(PropertyDescriptor t_pd)
        {
            return this;
        }

        #endregion
    }
}
--------------------编程问答-------------------- using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Generator.Design.BLL.Controls;
using System.Drawing.Design;

namespace Generator.Design.BLL
{
    public class PropertyChangeBase
    {
        /// <summary>
        /// 此方法是通用的,中间代理类的属性与源对象完全一样
        /// </summary>
        /// <param name="t_obj"></param>
        /// <returns></returns>
        public PropertyBaseCollection ObjectToPropertyBase(object t_obj)
        {
            PropertyDescriptorCollection ts = TypeDescriptor.GetProperties(t_obj);
            if (ts.Count <= 0)
            {
                return null;
            }
            int iCount = ts.Count;
            PropertyBaseCollection pts = new PropertyBaseCollection();

            #region 把属性存入中间类中

            for (int i = 0; i < iCount; i++)
            {
                PropertyBase pt = new PropertyBase();
                pt.Name = ts[i].Name;
                pt.Value = ts[i].GetValue(t_obj);
                pt.IsReadOnly = ts[i].IsReadOnly;
                pt.IsBrowsable = ts[i].IsBrowsable;
                pt.Category = ts[i].Category;
                if (!pt.IsReadOnly)
                {
                    if (ts[i].GetEditor(typeof(UITypeEditor)) != null)
                    {
                        pt.uiTypeConvertor = (UITypeEditor)ts[i].GetEditor(typeof(UITypeEditor));
                    }
                    else
                    {
                        pt.uiTypeConvertor = null;
                    }
                }
                else
                {
                    pt.uiTypeConvertor = null;

                }
                pt.Description = ts[i].Description;
                try
                {
                    pt.Converter = ts[i].Converter; ;
                }
                catch
                {
                    pt.Converter = ts[i].Converter;
                }

                pts.Add(pt);
            }
            #endregion

            return pts;
        }        
    }
}
--------------------编程问答-------------------- 一共有四个类,一个属性基类,一个属性类集合,一个属性描述类,一个中间类(用来动态改变属性的个数,其实是过滤一下而已),因为是继承接口,重写的方法和实现的方法比较多,但思路很简单,你可以参考一下,你的问题应该没这个复杂 --------------------编程问答-------------------- 谢谢 --------------------编程问答-------------------- --------------------编程问答-------------------- 不会,帮顶 --------------------编程问答-------------------- 支持搂主,收藏 --------------------编程问答-------------------- 都是很好的建议! 值得学习
补充:.NET技术 ,  .NET Framework
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,