我在绑定到BindingList的Win Forms应用程序中使用DataGridView,我希望改进业务逻辑和表示的“分离”。
在我的Form_Load事件中,我调用例程来构建BindingList,然后将DGV的.DataSource设置为此BindingList:
private void initializeFileList(string rootFolder) // populate grid with .xml filenames to be processed
{
String root = rootFolder;
var result = Directory.GetFiles(root, "*.xml", SearchOption.AllDirectories)
.Select(name => new InputFileInfo(name))
.ToList();
_filesToParse = new BindingList<InputFileInfo>(result.ToList());
dataGridView1.DataSource = _filesToParse;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.Columns["Rows"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dataGridView1.Columns["Message"].DefaultCellStyle.ForeColor = Color.Red;
这是困扰我的最后两个陈述;正如您所看到的,我希望对从“行”和“消息”属性创建的列进行细微的修饰。感觉很臭我应该在最后两行中硬编码我的自定义对象的属性。
是否有更优雅的方式来自定义DGV的这两列 - 目的是充分利用由以下提供的绑定: dataGridView1.DataSource = _filesToParse; 换句话说,仍然自定义列,但从“业务”对象中的某些内容而不是当前技术中执行此操作。
这是我的 InputFileInfo 类(来自同一解决方案中的另一个项目):
namespace CBMI.Common
{
public class InputFileInfo : INotifyPropertyChanged
{
private bool processThisFile;
public bool Process
{
get { return processThisFile; }
set
{
Utilities.Set(this, "Process", ref processThisFile, value, PropertyChanged);
}
}
public string FileName { get; set; }
private long rowsReturned;
public long Rows
{
get { return rowsReturned; }
set
{
Utilities.Set(this, "Rows", ref rowsReturned, value, PropertyChanged);
}
}
private string message;
public string Message
{
get { return message; }
set
{
Utilities.Set(this, "Message", ref message, value, PropertyChanged);
}
}
// constructor
public InputFileInfo(string fName)
{
Process = true;
FileName = fName;
Rows = 0;
Message = String.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
}
public static class Utilities
{
public static void Set<T>(object owner, string propName,
ref T oldValue, T newValue, PropertyChangedEventHandler eventHandler)
{
// make sure the property name really exists
if (owner.GetType().GetProperty(propName) == null)
{
throw new ArgumentException("No property named '" + propName + "' on " + owner.GetType().FullName);
}
// we only raise an event if the value has changed
if (!Equals(oldValue, newValue))
{
oldValue = newValue;
if (eventHandler != null)
{
eventHandler(owner, new PropertyChangedEventArgs(propName));
}
}
}
}
}
答案 0 :(得分:0)
我真的没有看到比你提供的更容易的替代解决方案。您不应该将某种CellStyle与数据绑定对象混合在一起,因为这不是一种好习惯。
我唯一建议的是禁用AutoGenerateColumns并定义自己的样式:
private static void AdditionalInitialization(DataGridView dgv, object dataSource) {
dgv.AutoGenerateColumns = false;
dgv.DataSource = dataSource; // Needs to occur after the auto generate columns is set to off
DataGridViewTextColumn msgCol = new DataGridViewTextColumn();
msgCol.HeaderText = "Message";
msgCol.DataPropertyName = "Message";
msgCol.DefaultCellStyle.ForeColor = Color.Red;
dgv.Columns.Add(msgCol);
}
这个方法可以放在你的任何类中,因为它是静态的,即你的InputFileInfo.cs
然后当你的表单加载时:
private void initializeFileList(string rootFolder) // populate grid with .xml filenames to be processed
{
String root = rootFolder;
var result = Directory.GetFiles(root, "*.xml", SearchOption.AllDirectories)
.Select(name => new InputFileInfo(name))
.ToList();
_filesToParse = new BindingList<InputFileInfo>(result.ToList());
InputFileInfo.AdditionalInitialization(datagridview1,_filesToParse);
}