WinForms DataGridView 자동 데이터 갱신 기법

방법 1: BindingList와 INotifyPropertyChanged 조합 (권장)

public class InventoryItem : INotifyPropertyChanged
{
    private string _itemName;
    private double _itemValue;

    public string ItemName
    {
        get => _itemName;
        set { _itemName = value; OnPropertyChanged(); }
    }

    public double ItemValue
    {
        get => _itemValue;
        set { _itemValue = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

public partial class InventoryView : Form
{
    private BindingList<InventoryItem> _inventory = new();
    private System.Timers.Timer _updateTimer = new(1500);

    public InventoryView()
    {
        InitializeComponent();
        itemGrid.DataSource = _inventory;
        _updateTimer.Elapsed += UpdateItemValues;
        _updateTimer.Start();
    }

    private void UpdateItemValues(object sender, ElapsedEventArgs e)
    {
        if (_inventory.Count == 0) return;
        
        var rand = new Random();
        foreach (var item in _inventory)
        {
            item.ItemValue *= 0.97 + rand.NextDouble() * 0.06;
        }
    }

    private void AddNewItem(object sender, EventArgs e)
    {
        _inventory.Add(new InventoryItem 
        { 
            ItemName = $"Item {_inventory.Count + 1}",
            ItemValue = new Random().Next(50, 500)
        });
    }
}

방법 2: DataTable을 이용한 데이터베이스 연동

public partial class SalesDashboard : Form
{
    private DataTable _salesData = new DataTable("Sales");
    private readonly System.Windows.Forms.Timer _dataTimer = new();

    public SalesDashboard()
    {
        InitializeComponent();
        
        _salesData.Columns.Add("ID", typeof(int));
        _salesData.Columns.Add("Product", typeof(string));
        _salesData.Columns.Add("Revenue", typeof(decimal));
        
        salesGrid.DataSource = _salesData;
        
        _dataTimer.Interval = 3000;
        _dataTimer.Tick += RefreshSalesData;
        _dataTimer.Start();
    }

    private void RefreshSalesData(object sender, EventArgs e)
    {
        if (_salesData.Rows.Count == 0) return;
        
        var rand = new Random();
        foreach (DataRow row in _salesData.Rows)
        {
            row["Revenue"] = (decimal)rand.Next(100, 5000);
        }
    }
}

방법 3: 수동 갱신 방식

public partial class ReportViewer : Form
{
    private BindingSource _reportSource = new();
    private List<ReportEntry> _reportData = new();

    public ReportViewer()
    {
        InitializeComponent();
        _reportSource.DataSource = _reportData;
        reportGrid.DataSource = _reportSource;
    }

    private void ReloadData()
    {
        // 데이터 재로딩 로직
        _reportSource.ResetBindings(false);
    }
    
    private void RefreshDisplay()
    {
        reportGrid.DataSource = null;
        reportGrid.DataSource = _reportData;
    }
}

핵심 구현 원리

  • 자동 갱신 메커니즘:
    • BindingList + INotifyPropertyChanged: 양방향 데이터 바인딩
    • DataTable: 내장 변경 알림 시스템
    • BindingSource.ResetBindings(): 수동 갱신 트리거
  • 성능 개선 기법:
    dataGridView.SuspendLayout();
    // 대량 데이터 처리
    dataGridView.ResumeLayout();
  • 스레드 안전성 보장:
    if (dataGrid.InvokeRequired)
    {
        dataGrid.Invoke(new Action(() => { /* UI 업데이트 */ }));
    }
  • 실시간 데이터베이스 연동:
    SqlDependency.Start(connectionString);
    SqlCommand cmd = new SqlCommand(query, conn);
    SqlDependency dependency = new SqlDependency(cmd);
    dependency.OnChange += (s, e) => LoadFreshData();

최적화 가이드라인

시나리오권장 방식
객체 컬렉션BindingList + INotifyPropertyChanged
데이터베이스 연동DataTable
단순 데이터 표시수동 갱신

성능 주의사항

// 대용량 데이터 처리
dataGridView.DoubleBuffered = true;
dataGridView.VirtualMode = true;

태그: WinForms DataGridView BindingList INotifyPropertyChanged DataTable

6월 11일 01:06에 게시됨