2011-08-09 38 views
0

BindingListにバインドされたWin FormsアプリケーションでDataGridViewを使用していますが、ビジネスの「分離」を改善したい論理とプレゼンテーション。私のForm_LoadイベントでグリッドがバインドされているBindingList <T>に基づいてDataGridViewのセルをカスタマイズする方法

、私がするBindingListを構築するためのルーチンを呼び出した後、私はこのするBindingListにDGVの.DataSourceを設定します。

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文です。ご覧のとおり、「行」と「メッセージ」プロパティから作成された列には微妙な外観上の変更が必要です。この最後の2行で私のカスタムオブジェクトのプロパティをハードコーディングしなければならないと感じました。

DGVの2つの列をカスタマイズするより洗練された方法がありますか?提供されるバインディングを完全に活用することを目標にしてください: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

私は本当にしようとしている別の解決策が表示されませんあなたが提供したものより簡単になります。 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); 

}

関連する問題