Question

J'ai System.Data.DataRows avec plusieurs champs, la plupart d'entre eux seulement types simples comme int, simple, string.

Quelle est la meilleure façon de les rendre modifiables à l'aide d'un PropertyGrid? il devrait fonctionner automatiquement, peu importe quel type de champs DataRow a, mais il ne doit pas les afficher tous. Je veux fournir une liste des propriétés qui doivent être cachés.

depuis le DataTable est autogénérée je ne peux pas ajouter des attributs personnalisés comme [Browsable (false)]

Merci beaucoup!

Était-ce utile?

La solution

Edité pour gérer le filtrage; beaucoup Tricker: en plus d'obtenir le DataRowView, nous devons fournir un composant personnalisé qui prétend (via pass-thru PropetyDescriptors) être le DataRowView (qui se prétend être le DataRow) - et filtrer les propriétés que nous n » t veulent.

problème très intéressant ;-P plus facile à résoudre dans les classes classiques, mais les travaux ci-dessous pour ;-p DataRow

Notez que vous pouvez faire d'autres choses dans ce domaine pour faire certaines des propriétés non modifiable (IsReadOnly), ou une autre légende (DisplayName) ou catégorie (Category) - en remplaçant les autres membres dans 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; }
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top