문제

나는 여러 필드가있는 System.data.datarows를 가지고 있으며, 대부분은 int, single, string과 같은 일반 유형입니다.

PropertyGrid를 사용하여 편집 가능한 가장 좋은 방법은 무엇입니까? Datarow가 어떤 종류의 필드를 가지고 있는지에 관계없이 자동으로 작동해야하지만 모든 필드를 표시해서는 안됩니다. 숨겨져야 할 속성 목록을 제공하고 싶습니다.

DataTable이 자동 생성되어 있으므로 [Browsable (False)]와 같은 사용자 지정 속성을 추가 할 수 없습니다.

정말 감사합니다!

도움이 되었습니까?

해결책

필터링을 처리하도록 편집; 많은 속임수 : 얻는 것 외에도 DataRowView, 우리는 척하는 사용자 지정 구성 요소를 제공해야합니다 (Pass-Thru를 통해 PropetyDescriptors) DataRowView (그 자체가 척하는 척합니다 DataRow) - 우리가 원하지 않는 속성을 걸러냅니다.

매우 흥미로운 문제; -P 고전 수업에서 해결하기 쉽지만 아래는 작동합니다. DataRow ;-피

이 영역에서 다른 일을하기 위해 속성 중 일부를 편집 할 수 없게 만들 수 있습니다 (IsReadOnly), 또는 다른 캡션이 있습니다 (DisplayName) 또는 카테고리 (Category) - 다른 회원을 우선시하여 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; }
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top