使用属性指定列 FillWeight
Using an attribute to specify a columns FillWeight
我有一个用 BindingList 填充的 DataGridView。 BindingList 是一个 SyncDetail
类型的列表,它有很多属性。在这些属性中我可以使用属性来决定是否不显示列(Browsable(false)
),列的显示名称(DisplayName("ColumnName")
)等。示例如下:
public class SyncDetail : ISyncDetail
{
// Browsable properties
[DisplayName("Sync Name")]
public string Name { get; set; }
// Non browsable properties
[Browsable(false)]
[XmlIgnore]
public bool Disposed { get; set; }
}
有没有一种方法可以使用属性来定义应设置的列宽?例如[ColumnWidth(200)]
。如果可能,我想设置 FillWeight
,因为我的 AutoSizeColumnsMode
设置为 Fill
。
谢谢。
我最终实现了一个自定义属性来做到这一点。
public class ColumnWeight : Attribute
{
public int Weight { get; set; }
public ColumnWeight(int weight)
{
Weight = weight;
}
}
然后我可以重写 DataGridView 的 OnColumnAdded 方法来获取属性并为列设置 FillWeight。
protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
{
// Get the property object based on the DataPropertyName of the column
var property = typeof(SyncDetail).GetProperty(e.Column.DataPropertyName);
// Get the ColumnWeight attribute from the property if it exists
var weightAttribute = (ColumnWeight)property.GetCustomAttribute(typeof(ColumnWeight));
if (weightAttribute != null)
{
// Finally, set the FillWeight of the column to our defined weight in the attribute
e.Column.FillWeight = weightAttribute.Weight;
}
base.OnColumnAdded(e);
}
然后我可以在我的对象的属性上设置属性。
public class SyncDetail : ISyncDetail
{
// Browsable properties
[DisplayName("Sync Name")]
[ColumnWeight(20)]
public string Name { get; set; }
etc...
}
根据您最初的回答,我做了一些 稍微 扩展的用例,可以与多个数据网格一起使用,这些数据网格绑定到以整数值支持的不同 Column 属性。
在 SyncDetails 中使用 Width 和 MinimumWidth 属性的示例 class:
[ColumnProperty("MinimumWidth",100)]
[ColumnProperty("Width",250 )]
public string Name{get;set;}
然后我的属性定义被更新为允许多个属性:
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class ColumnPropertyAttribute:Attribute
{
public string ColumnPropertyName { get; set; }
public int ColumnValue { get; set; }
public ColumnPropertyAttribute(string columnPropertyName, int columnValue)
{
ColumnValue = columnValue;
ColumnPropertyName = columnPropertyName;
}
}
在 _ColumnAdded 事件中,我们查找数据网格绑定到的任何类型,从中提取自定义属性,然后尝试应用该值。我将所有内容绑定到 BindingList<T>
,因此 .GetGenericArguments() returns 为自定义属性查找键入 T,但可以根据其他应用程序的需要进行调整。
private void DataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
try
{
var propInfo = (sender as DataGridView).DataSource.GetType().GetGenericArguments()[0].GetProperty(e.Column.DataPropertyName);
if (propInfo != null)
{
var customAttributes = propInfo.GetCustomAttributes<ColumnPropertyAttribute>();
foreach (var ca in customAttributes)
{
var column = e.Column;
var propToChange = e.Column.GetType().GetProperty(ca.ColumnPropertyName);
propToChange.SetValue(column, ca.ColumnValue);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception processing custom _ColumnAdded properties: " + ex.Message);
}
}
我有一个用 BindingList 填充的 DataGridView。 BindingList 是一个 SyncDetail
类型的列表,它有很多属性。在这些属性中我可以使用属性来决定是否不显示列(Browsable(false)
),列的显示名称(DisplayName("ColumnName")
)等。示例如下:
public class SyncDetail : ISyncDetail
{
// Browsable properties
[DisplayName("Sync Name")]
public string Name { get; set; }
// Non browsable properties
[Browsable(false)]
[XmlIgnore]
public bool Disposed { get; set; }
}
有没有一种方法可以使用属性来定义应设置的列宽?例如[ColumnWidth(200)]
。如果可能,我想设置 FillWeight
,因为我的 AutoSizeColumnsMode
设置为 Fill
。
谢谢。
我最终实现了一个自定义属性来做到这一点。
public class ColumnWeight : Attribute
{
public int Weight { get; set; }
public ColumnWeight(int weight)
{
Weight = weight;
}
}
然后我可以重写 DataGridView 的 OnColumnAdded 方法来获取属性并为列设置 FillWeight。
protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
{
// Get the property object based on the DataPropertyName of the column
var property = typeof(SyncDetail).GetProperty(e.Column.DataPropertyName);
// Get the ColumnWeight attribute from the property if it exists
var weightAttribute = (ColumnWeight)property.GetCustomAttribute(typeof(ColumnWeight));
if (weightAttribute != null)
{
// Finally, set the FillWeight of the column to our defined weight in the attribute
e.Column.FillWeight = weightAttribute.Weight;
}
base.OnColumnAdded(e);
}
然后我可以在我的对象的属性上设置属性。
public class SyncDetail : ISyncDetail
{
// Browsable properties
[DisplayName("Sync Name")]
[ColumnWeight(20)]
public string Name { get; set; }
etc...
}
根据您最初的回答,我做了一些 稍微 扩展的用例,可以与多个数据网格一起使用,这些数据网格绑定到以整数值支持的不同 Column 属性。
在 SyncDetails 中使用 Width 和 MinimumWidth 属性的示例 class:
[ColumnProperty("MinimumWidth",100)]
[ColumnProperty("Width",250 )]
public string Name{get;set;}
然后我的属性定义被更新为允许多个属性:
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class ColumnPropertyAttribute:Attribute
{
public string ColumnPropertyName { get; set; }
public int ColumnValue { get; set; }
public ColumnPropertyAttribute(string columnPropertyName, int columnValue)
{
ColumnValue = columnValue;
ColumnPropertyName = columnPropertyName;
}
}
在 _ColumnAdded 事件中,我们查找数据网格绑定到的任何类型,从中提取自定义属性,然后尝试应用该值。我将所有内容绑定到 BindingList<T>
,因此 .GetGenericArguments() returns 为自定义属性查找键入 T,但可以根据其他应用程序的需要进行调整。
private void DataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
try
{
var propInfo = (sender as DataGridView).DataSource.GetType().GetGenericArguments()[0].GetProperty(e.Column.DataPropertyName);
if (propInfo != null)
{
var customAttributes = propInfo.GetCustomAttributes<ColumnPropertyAttribute>();
foreach (var ca in customAttributes)
{
var column = e.Column;
var propToChange = e.Column.GetType().GetProperty(ca.ColumnPropertyName);
propToChange.SetValue(column, ca.ColumnValue);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception processing custom _ColumnAdded properties: " + ex.Message);
}
}