C#/的WinForms:如何最好地绑定一个PropertyGrid中和的System.Data.DataRow [英] C#/winforms: how to best bind a propertygrid and a System.Data.DataRow

查看:167
本文介绍了C#/的WinForms:如何最好地绑定一个PropertyGrid中和的System.Data.DataRow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有System.Data.DataRows几个领域,大多只是普通的类型如int,单,字符串。

i have System.Data.DataRows with several fields, most of them just plain types like int, single, string.

什么是使用PropertyGrid中,使它们可编辑的最佳方式?
它会自动工作,无论数据行有什么样的领域,但它不应该显示他们。我想提供应该被隐藏的属性列表。

what is the best way to make them editable using a propertygrid? it should work automatically no matter what kind of fields the datarow has, but it should not display all of them. i want to provide a list of properties that should be hidden.

由于数据表是自动生成的,我不能添加自定义属性,如[可浏览(假)]

since the DataTable is autogenerated i cannot add custom attributes like [Browsable(false)]

非常感谢!

推荐答案

编辑处理过滤;很多tricker:除了获得 DataRowView的,我们需要提供pretends(通过自定义组件直通 PropetyDescriptor S)是 DataRowView的(它本身是pretending是的DataRow ) - 并过滤掉我们不想要的属性。

Edited to handle filtering; much tricker: in addition to getting the DataRowView, we need to provide a custom component that pretends (via pass-thru PropetyDescriptors) to be the DataRowView (which is itself pretending to be the DataRow) - and filter out the properties that we don't want.

;-p更易非常有趣的问题,在经典类解决,但低于适用于的DataRow ;-p

Very interesting problem ;-p Easier to solve in classic classes, but the below works for DataRow ;-p

请注意,你可以做其他的事情在这方面做的一些属性不可编辑的( IsReadOnly )的,或有不同的标题(显示名称)或类别(类别) - 由 RowWrapperDescriptor 。

Note that you could do other things in this area to make some of the properties non-editable (IsReadOnly), or have a different caption (DisplayName), or category (Category) - by overriding other members in RowWrapperDescriptor.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
static class program
{
    [STAThread]
    static void Main()
    {
        DataTable table = new DataTable();
        table.Columns.Add("ID", typeof(int));
        table.Columns.Add("Foo", typeof(int));
        table.Columns.Add("Bar", typeof(string));
        table.Columns.Add("Audit", typeof(DateTime));

        table.Rows.Add(1, 14, "abc", DateTime.MinValue);
        DataRow row = table.Rows.Add(2,13,"def", DateTime.MinValue);
        table.Rows.Add(3, 24, "ghi", DateTime.MinValue);

        RowWrapper wrapper = new RowWrapper(row);
        wrapper.Exclude.Add("ID");
        wrapper.Exclude.Add("Bar");

        Application.EnableVisualStyles();
        Application.Run(new Form {Controls = {
            new PropertyGrid { Dock = DockStyle.Fill,
                SelectedObject = wrapper}}});
    }
}

[TypeConverter(typeof(RowWrapper.RowWrapperConverter))]
class RowWrapper
{
    private readonly List<string> exclude = new List<string>();
    public List<string> Exclude { get { return exclude; } }
    private readonly DataRowView rowView;
    public RowWrapper(DataRow row)
    {
        DataView view = new DataView(row.Table);
        foreach (DataRowView tmp in view)
        {
            if (tmp.Row == row)
            {
                rowView = tmp;
                break;
            }
        }
    }
    static DataRowView GetRowView(object component)
    {
        return ((RowWrapper)component).rowView;
    }
    class RowWrapperConverter : TypeConverter
    {
        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override PropertyDescriptorCollection GetProperties(
            ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            RowWrapper rw = (RowWrapper)value;
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(
                GetRowView(value), attributes);
            List<PropertyDescriptor> result = new List<PropertyDescriptor>(props.Count);
            foreach (PropertyDescriptor prop in props)
            {
                if (rw.Exclude.Contains(prop.Name)) continue;
                result.Add(new RowWrapperDescriptor(prop));
            }
            return new PropertyDescriptorCollection(result.ToArray());
        }
    }
    class RowWrapperDescriptor : PropertyDescriptor
    {
        static Attribute[] GetAttribs(AttributeCollection value)
        {
            if (value == null) return null;
            Attribute[] result = new Attribute[value.Count];
            value.CopyTo(result, 0);
            return result;
        }
        readonly PropertyDescriptor innerProp;
        public RowWrapperDescriptor(PropertyDescriptor innerProperty)
            : base(
                innerProperty.Name, GetAttribs(innerProperty.Attributes))
        {
            this.innerProp = innerProperty;
        }


        public override bool ShouldSerializeValue(object component)
        {
            return innerProp.ShouldSerializeValue(GetRowView(component));
        }
        public override void ResetValue(object component)
        {
            innerProp.ResetValue(GetRowView(component));
        }
        public override bool CanResetValue(object component)
        {
            return innerProp.CanResetValue(GetRowView(component));
        }
        public override void SetValue(object component, object value)
        {
            innerProp.SetValue(GetRowView(component), value);
        }
        public override object GetValue(object component)
        {
            return innerProp.GetValue(GetRowView(component));
        }
        public override Type PropertyType
        {
            get { return innerProp.PropertyType; }
        }
        public override Type ComponentType
        {
            get { return typeof(RowWrapper); }
        }
        public override bool IsReadOnly
        {
            get { return innerProp.IsReadOnly; }
        }
    }
}

这篇关于C#/的WinForms:如何最好地绑定一个PropertyGrid中和的System.Data.DataRow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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