PropertyGrid с возможно нулевым списком
Я использую класс PropertyGrid для редактирования объектов в моем приложении. Это соответствующие классы (или, скорее, их упрощения):
public class Inner
{
public int A { get; set; }
public string B { get; set; }
}
public class Outer
{
public List<Inner> InnerData { get; set; }
public int Id { get; set; }
}
Я установлю объект типа Outer в качестве поля SelectedObject моей сетки свойств. Проблема возникает, когда для объекта Outer свойство InnerData имеет значение NULL. Нулевое значение считается приемлемым значением для этого свойства, поскольку свойство InnerData представляет "необязательные" данные, и отсутствие его указания - это не то же самое, что указание пустого списка. В идеале я хотел бы, чтобы пользователь мог заменить нулевое свойство InnerData реальным значением, указав компоненты нового списка, изменить существующее ненулевое значение InnerData и заменить существующее значение InnerData нулевым.
Кто-нибудь знает, как это сделать?
2 ответа
Посмотрите на создание UITypeEditor, я думаю, что если вы используете редактор, вы будете иметь больше контроля над списком и сможете определить, является ли текущее значение нулевым, и если да, то вы можете иметь редактор, показывающий пустую сетку или что-то такое, где Элементы списка могут быть добавлены или удалены, вы также можете добавить флажок, чтобы сказать редактору, что он должен возвращать null снова, и установить значение null для свойства, редактор по сути является WinForm, так что вы можете делать в нем практически все.
internal class GenericTypeEditor : UITypeEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService winFormEditorSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
using (MyForm editorForm = new MyForm())
{
if (winFormEditorSvc.ShowDialog(editorForm) == System.Windows.Forms.DialogResult.OK)
value = editorForm.ReturnObject;
}
return value; //this can be null if you wish
}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
Затем просто установите атрибут в вашей собственности
[EditorAttribute(typeof(GenericTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List<Inner> InnerData { get; set; }
Эта статья помогла мне в прошлом, может быть, она вам поможет: http://msdn.microsoft.com/en-us/library/ms171840(v=vs.100).aspx
Сетка свойств пытается добавить новые внутренние элементы в объект InnerData, но, поскольку вы не инициализировали его, в сетке свойств нет места для сохранения добавленных элементов. Вам нужен конструктор в Outter, который инициализирует InnerData как новый список. Вам не нужно помещать в него какие-либо элементы, пользователь может делать это во время выполнения и также может очищать их обратно, но объект списка InnerData должен быть инициализирован.
Если вы просто хотите, чтобы Inner был свойством, добавьте System.ComponentModel к вашему использованию и попробуйте это
[TypeConverter(typeof(ExpandableTypeConverter))]
public Inner DefaultInner { get; set; }
Это сделает ваш объект расширяемым в сетке свойств, чтобы вы могли установить его вложенные свойства
Попробуйте обработать событие PropertyGrid.SelectedGridItemChanged:
private void propertyGrid1_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
if ((e.NewSelection.Label == "InnerData") && (_outter.InnerData == null)) _outter.InnerData = new List<Inner>();
}
Затем каждый раз, когда выбирается элемент InnerData, если коллекция пуста, она инициализируется в новый список.