0

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;

気になるのは最後の 2 つのステートメントです。ご覧のとおり、"Rows" プロパティと "Message" プロパティから作成された列に外観上の小さな変更を加えたいと思います。この最後の 2 行でカスタム オブジェクトのプロパティをハードコーディングしなければならないのは、臭く感じます。

dataGridView1.DataSource = _filesToParse;によって提供されるバインディングを完全に活用することを目的として、DGV のこれら 2 つの列をカスタマイズするより洗練された方法はありますか? つまり、列をカスタマイズすることはできますが、現在の手法ではなく、「ビジネス」オブジェクトの何かからカスタマイズします。

これが私の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));
        }
    }
}

}

}

4

1 に答える 1

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);

}

于 2011-08-09T18:27:38.263 に答える