C# PropertyGrid属性下拉框问题

fenghuoyun123 2017-07-12 08:07:43
private int deviceType = 0;
[TypeConverter(typeof(DeviceTypeConverter))]
[DisplayName("设备类型")]
public int DeviceType
{
get { return deviceType; }
set { deviceType= value; }
}

deviceType为int类型,但是在PropertyGrid中需要显示为下拉框的形式,而且显示的是名称,不是int数字
DeviceTypeConverter可以将PropertyGrid的设备类型设置为"设备类型1","设备类型2","设备类型3"下拉框,
但是打开PropertyGrid后,设备类型显示的是0,不是“设备类型1"
①怎么做到在打开PropertyGrid时,根据deviceType,显示相应的名称,而不是数字
②还有就是怎么能在选择“设备类型1"后,deviceType自动设置为0,选择“设备类型2"后,deviceType自动设置为1呢
③在选择某个下拉框后,想设置其他的PropertyGrid属性的显示或者不显示,可以灵活做到嘛,感觉在网上查到的资料都没有这种动态设置属性的显示或者不显示的
...全文
1073 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
完美世界ssrs 2019-06-05
  • 打赏
  • 举报
回复
怎么解决的能跟大家说一下吗,感谢
fenghuoyun123 2017-07-14
  • 打赏
  • 举报
回复
感谢各位,已解决
assky124 2017-07-14
  • 打赏
  • 举报
回复
自定义UITypeEditor 就行了

        /// <summary>
        /// 页面类型
        /// </summary>
        [Editor(typeof(PageTypeEditor), typeof(UITypeEditor))]
        public string PageType
        {
            get;
            set;
        }

    internal class PageTypeEditor:UITypeEditor
    {
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            //return base.EditValue(context, provider, value);
            var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSvc != null)
            {
                PageTypeDropdown dropList = new PageTypeDropdown();
                var str = string.Empty;
                if (value != null)
                {
                    str = value.ToString();
                }
                if(!string.IsNullOrEmpty(str) && !dropList.ContainItemText(str))
                {
                    dropList.Items.Insert(0,str);
                }
                dropList.Text = str;
                dropList.EditorService = edSvc;
                edSvc.DropDownControl(dropList);
                return dropList.Text;
            }
            return value;
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            //return base.GetEditStyle(context);
            return UITypeEditorEditStyle.DropDown;
        }
    }

    internal class PageTypeDropdown : ListView
    {
        public PageTypeDropdown()
        {
            this.View = System.Windows.Forms.View.List;
            this.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.MultiSelect = false;
            this.FullRowSelect = true;
            this.Items.Add("内容页");
            this.Items.Add("封面");
        }

        public override string Text
        {
            get
            {
                return GetSeletedText();
            }
            set
            {
                SetSelectItem(value);
            }
        }

        public IWindowsFormsEditorService EditorService
        {
            get;
            set;
        }

        public bool ContainItemText(string text)
        {
            foreach (ListViewItem item in Items)
            {
                if (item.Text == text)
                {
                    return true;
                }
            }
            return false;
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            CloseDropDown();
        }

        private void CloseDropDown()
        {
            if (EditorService != null)
            {
                EditorService.CloseDropDown();
            }
        }

        private string GetSeletedText()
        {
            if (this.SelectedItems.Count > 0)
            {
                var item = SelectedItems[0];
                return item.Text;
            }
            return string.Empty;
        }

        private void SetSelectItem(string text)
        {
            foreach (ListViewItem item in Items)
            {
                if (item.Text == text)
                {
                    item.Selected = true;
                    break;
                }
            }
        }
    }
xdashewan 2017-07-14
  • 打赏
  • 举报
回复
引用 7 楼 fenghuoyun123 的回复:
种方式不行呀,这么设置完之后,PropertyGrid没有实时变化,而把PropertyGrid关了之后再打开PropertyGrid,所有的属性标签都没了,感觉这种方式是永久性的设置属性值
写在其他属性的set方法里,亲测完全可以实时变化
xdashewan 2017-07-13
  • 打赏
  • 举报
回复
引用 5 楼 fenghuoyun123 的回复:
还有最后一个问题呢 在PropertyGrid显示以后,选择了某个下拉框时,想设置其他的PropertyGrid属性的显示或者不显示,可以做到嘛
可以做到,利用反射标签属性BrowsableAttribute,改变其值

Type type = typeof(System.ComponentModel.BrowsableAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance);
            fld.SetValue(attrs[type], readOnly);
fenghuoyun123 2017-07-13
  • 打赏
  • 举报
回复
引用 4 楼 u012948520 的回复:
        [Browsable(true), DefaultValue(TTT.t1)]
        public TTT Test
        {
            get;
            set;
        }

        public enum TTT
        {
            t1,
            t2,
            t3
        }
把属性又int改枚举是可以的
->枚举的值必须是固定的,但是我这个不是,是可以动态增加的 但是使用TypeConverter也解决了,可以动态设置 还有最后一个问题呢 在PropertyGrid显示以后,选择了某个下拉框时,想设置其他的PropertyGrid属性的显示或者不显示,可以做到嘛
白衣如花 2017-07-13
  • 打赏
  • 举报
回复
        [Browsable(true), DefaultValue(TTT.t1)]
        public TTT Test
        {
            get;
            set;
        }

        public enum TTT
        {
            t1,
            t2,
            t3
        }
把属性又int改枚举是可以的
xdashewan 2017-07-13
  • 打赏
  • 举报
回复
方法1:直接把DeviceType类型变为枚举,前提是枚举中值是已知的,且不会动态增加 方法2:利用TypeConverter,这里有篇文章有具体例子,可以参考下http://blog.csdn.net/luyifeiniu/article/details/5426960
白衣如花 2017-07-13
  • 打赏
  • 举报
回复
引用 1 楼 shoppo0505 的回复:
PropertyGrid是属性面板。。。。 这个题主应该是自定义控件的属性,在属性面板中显示和预期不符
shoppo0505 2017-07-13
  • 打赏
  • 举报
回复
PropertyGrid是什么?也不太明白你的问题。 一般下拉框都有两个属性,一个是displaymember,一个是valuemember,你将这两个属性的值,设置成你帮定数据源里面的property名字就可以了。当然,这个时候,帮定单一基本属性的list什么的就不行了。帮定的对象,至少需要两个属性。 栗子: classe Device { private int id; private string name; getter.... setter.. public Device() } 然后 List<Device> list = .... Device obj = new Device(); obj.id = 1; obj.name = "name1"; list.add(obj); 这个list再帮定到下拉框就可以了。
fenghuoyun123 2017-07-13
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 fenghuoyun123 的回复:] 还有最后一个问题呢 在PropertyGrid显示以后,选择了某个下拉框时,想设置其他的PropertyGrid属性的显示或者不显示,可以做到嘛
可以做到,利用反射标签属性BrowsableAttribute,改变其值

Type type = typeof(System.ComponentModel.BrowsableAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance);
            fld.SetValue(attrs[type], readOnly);
[/quote]
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 fenghuoyun123 的回复:] 还有最后一个问题呢 在PropertyGrid显示以后,选择了某个下拉框时,想设置其他的PropertyGrid属性的显示或者不显示,可以做到嘛
可以做到,利用反射标签属性BrowsableAttribute,改变其值

Type type = typeof(System.ComponentModel.BrowsableAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance);
            fld.SetValue(attrs[type], readOnly);
[/quote] 这种方式不行呀,这么设置完之后,PropertyGrid没有实时变化,而把PropertyGrid关了之后再打开PropertyGrid,所有的属性标签都没了,感觉这种方式是永久性的设置属性值

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧