我有一个绑定到List的datagridView。此List由我的类组成,其中包含2个公共属性,一个String Name和另一个List CustomList。见下文:
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列,并显示类似“Collection”的内容,其中显示“...”按钮,以及点击它时弹出“Collection Editor”
有谁知道这是否可行以及如何启用它?如果有一个教程或任何可以帮助我的东西,我也会感激。谢谢。
答案 0 :(得分:2)
我认为使用泛型是一个干净的解决方案:
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 :(得分:1)
简答:是的,你可以用一些代码来完成。
答案很长:编写代码会让人痛苦,因为您不仅要知道DataGridView在自定义列中的行为,还需要知道如何在运行时公开设计时元素,这需要相当多的管道。还必须了解有关PropertyGrid的广泛知识。
注意:这可能是一个有趣的组件。 (如果我有时间的话,我可能会解决这个问题)
答案 2 :(得分:1)
所以使用Dave发布的'button'方法,以及我发现的一些实现CollectionEditor的代码,我可以编辑MyClass2中的CustomList
这是我的解决方案,虽然不像我想的那么干净:
把这个课放在某个地方:
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用来在PropertyGrid中添加TabPages ...通过显示“...”按钮......但这可能现在有效。
答案 3 :(得分:0)
您要做的是添加一个带有按钮的列模板:
http://geekswithblogs.net/carmelhl/archive/2008/11/11/126942.aspx
在按钮的处理程序中,从集合中获取所选的MyClass
项,并将其list属性绑定到弹出窗口中的网格。