DataGridView List <T>столбец? - PullRequest
       27

DataGridView List <T>столбец?

2 голосов
/ 17 августа 2010

У меня есть datagridView, который привязан к списку.Этот список состоит из моего класса, который содержит 2 открытых свойства, имя строки и другой список пользовательских списков.См. Ниже:

public class MyClass2
{        
    public string Name
    { get; set;}


    public string Description
    {
        get;
        set;
    }
}

public class MyClass
{
    List<MyClass2> myList;

    public string Name
    {
        get;
        set;
    }

    public List<MyClass2> CustomList
    {
        get { return myList ?? (myList= new List<MyClass2>()); }
    }

}

А затем на моей странице дизайнера:

List<MyClass> myClassList = new List<MyClass>();
dataGridView.DataSource = myClassList;

Как и сейчас, единственным столбцом, который появляется в сетке, является столбец MyClass: Name,и столбец CustomList не отображается.Мне бы хотелось, чтобы в столбце CustomList отображалось и отображалось что-то вроде «Коллекция» с отображаемой кнопкой «...», и при нажатии на нее появлялся «Редактор коллекции».

Кто-нибудь знает, возможно ли это и как его включить?Если есть учебник или что-нибудь, что могло бы помочь мне, я бы это тоже оценил.Благодарю.

Ответы [ 4 ]

2 голосов
/ 07 сентября 2012

Использование дженериков, я думаю, является чистым решением:

public class Sorter<T>: IComparer<T>
{
    public string Propiedad { get; set; }

    public Sorter(string propiedad)
    {
        this.Propiedad = propiedad;
    }

    public int Compare(T x, T y)
    {
        PropertyInfo property = x.GetType().GetProperty(this.Propiedad);
        if (property == null)
            throw new ApplicationException("El objeto no tiene la propiedad " + this.Propiedad);
        return Comparer.DefaultInvariant.Compare(property.GetValue(x, null), property.GetValue(y, null));
    }
}

Пример использования:

string orderBy = "propertyName";
bool orderAsc = true;

List<MyExampleClass> myClassList = someMethod();

if (!string.IsNullOrEmpty(orderBy))
{
    myClassList.Sort(new Sorter<MyExampleClass>(orderBy));
    if (!orderAsc) myClassList.Reverse();
}
1 голос
/ 18 августа 2010

Краткий ответ: Да, вы можете сделать это с помощью некоторого кода.

Длинный ответ: Писать код будет непросто, так как вам нужно будет знать не только то, как DataGridView ведет себя с пользовательскими столбцами, но вам нужно знать, как выставлять Время разработки элементов во время выполнения, что требует немало сантехники. Обширные знания о PropertyGrid также должны быть известны.

Примечание: Это может быть забавный компонент для написания. (Я мог бы на самом деле заняться этим, если у меня будет время)

1 голос
/ 18 августа 2010

Таким образом, используя подход «кнопки», опубликованный Дейвом, и некоторый код, который я нашел, который реализует CollectionEditor, я могу редактировать CustomList в MyClass2

Вот мое решение, хотя и не такое чистое, как хотелось бы:

Поместите этот класс куда-нибудь:

class MyHelper : IWindowsFormsEditorService, IServiceProvider, ITypeDescriptorContext
{
    public static void EditValue(IWin32Window owner, object component, string propertyName)
    {
        PropertyDescriptor prop = TypeDescriptor.GetProperties(component)[propertyName];
        if (prop == null) throw new ArgumentException("propertyName");
        UITypeEditor editor = (UITypeEditor)prop.GetEditor(typeof(UITypeEditor));
        MyHelper ctx = new MyHelper(owner, component, prop);
        if (editor != null && editor.GetEditStyle(ctx) == UITypeEditorEditStyle.Modal)
        {
            object value = prop.GetValue(component);
            value = editor.EditValue(ctx, ctx, value);
            if (!prop.IsReadOnly)
            {
                prop.SetValue(component, value);
            }
        }
    }
    private readonly IWin32Window owner;
    private readonly object component;
    private readonly PropertyDescriptor property;
    private MyHelper(IWin32Window owner, object component, PropertyDescriptor property)
    {
        this.owner = owner;
        this.component = component;
        this.property = property;
    }
    #region IWindowsFormsEditorService Members

    public void CloseDropDown()
    {
        throw new NotImplementedException();
    }

    public void DropDownControl(System.Windows.Forms.Control control)
    {
        throw new NotImplementedException();
    }

    public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form dialog)
    {
        return dialog.ShowDialog(owner);
    }

    #endregion

    #region IServiceProvider Members

    public object GetService(Type serviceType)
    {
        return serviceType == typeof(IWindowsFormsEditorService) ? this : null;
    }

    #endregion

    #region ITypeDescriptorContext Members

    IContainer ITypeDescriptorContext.Container
    {
        get { return null; }
    }

    object ITypeDescriptorContext.Instance
    {
        get { return component; }
    }

    void ITypeDescriptorContext.OnComponentChanged()
    { }

    bool ITypeDescriptorContext.OnComponentChanging()
    {
        return true;
    }

    PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
    {
        get { return property; }
    }

    #endregion

Добавление столбца кнопки в сетку данных:

DataGridViewButtonColumn butt = new DataGridViewButtonColumn();
butt.HeaderText = "CustomList";
butt.Name = "CustomList";
butt.Text = "Edit CustomList...";
butt.UseColumnTextForButtonValue = true;

dataGridView.Columns.Add(butt);
dataGridView.CellClick += new DataGridViewCellEventHandler(dataGridView_CellClick);

Затем вызовите его в обработчике кнопки щелчка ячейки.

if (e.RowIndex < 0 || e.ColumnIndex != dataGridView.Columns["CustomList"].Index)
            return;

//get the name of this column
string name = (string)dataGridView[dataGridView.Columns["Name"].Index, e.RowIndex].Value;

var myClassObject= myClassList.Find(o => o.Name == name);

MyHelper.EditValue(this, myClassObject, "CustomList");

Мне все еще было бы интересно услышать другие подходы, и мне не пришлось бы реализовывать свой собственный CollectionEditor. И я все еще заинтересован в том, чтобы это выглядело больше как то, что TabControl использует для добавления TabPages в PropertyGrid ... путем отображения кнопки "..." ... но это может сработать на данный момент.

0 голосов
/ 18 августа 2010

Что вы хотите сделать, это добавить шаблон столбца с кнопкой в ​​нем:

http://geekswithblogs.net/carmelhl/archive/2008/11/11/126942.aspx

В обработчике для кнопки получить выбранный элемент MyClass изколлекции и свяжите его свойство списка с сеткой в ​​вашем всплывающем окне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...