3

switch ステートメントを使用してダブルクリック イベントによってフィルター処理される datagridview があります。データ ソースは、最初はユーザー入力に基づいて LINQ to SQL クエリによって設定されます。次に、セルをダブルクリックして、モデル、コンピューター名、オペレーティング システムなどのアイテムをフィルター処理するオプションがあります。

ここには重複したコードが多すぎるようです。これを行うためのより良い方法について何か考えはありますか?

private void gridInventory_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
        try
        {
            if (e.ColumnIndex > 0 && e.RowIndex > 0)
            {
                var cell = this.gridInventory[e.ColumnIndex, e.RowIndex];
                var clickedValue = (cell.Value != null) ? cell.Value.ToString() : string.Empty;

                if (!string.IsNullOrEmpty(clickedValue))
                {
                    switch (this.gridInventory.Columns[e.ColumnIndex].Name.ToUpper())
                    {
                        case @"MODEL":
                            CurrentList = CurrentList.Where(r => r.Model != null && r.Model.ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"COMPUTERNAME":
                            CurrentList = CurrentList.Where(r => r.ComputerName != null && r.ComputerName.ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"SERIALNUMBER":
                            CurrentList = CurrentList.Where(r => r.SerialNumber != null && r.SerialNumber.ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"COMPUTERID":
                            CurrentList = CurrentList.Where(r => r.ComputerID.ToString().ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"MANUFACTURER":
                            CurrentList = CurrentList.Where(r => r.Manufacturer != null && r.Manufacturer.ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"OSVERSION":
                            CurrentList = CurrentList.Where(r => r.OSVersion != null && r.OSVersion.ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"AUDITDATE":
                            CurrentList = CurrentList.Where(r => r.AuditDate != null && r.AuditDate.ToString().ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        case @"AUDITGUID":
                            CurrentList = CurrentList.Where(r => r.AuditGUID != null && r.AuditGUID.ToString().ToUpper() == clickedValue.ToUpper()).ToList();
                            break;
                        default:
                            break;
                    }

                    if (this.CurrentList != null)
                    {
                        gridInventory.DataSource = this.CurrentList;
                        this.lblRecords.Text = string.Format(@"Total Records: {0}", CurrentList.Count(c => c.ComputerID > 0));
                    }
                }
            }
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, @"error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
4

1 に答える 1

1

LINQ とリフレクションを使用すると、この関数は次のように書き直すことができます。

private void gridInventory_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
        try
        {
            if (e.ColumnIndex > 0 && e.RowIndex > 0)
            {
                var cell = this.gridInventory[e.ColumnIndex, e.RowIndex];
                var clickedValue = (cell.Value != null) ? cell.Value.ToString() : string.Empty;
                if (!string.IsNullOrEmpty(clickedValue))
                {
                    CurrentList = CurrentList.Where(r => typeof(r_type_here).GetProperty(this.gridInventory.Columns[e.ColumnIndex].Name).GetValue(r, null) != null &&
                        typeof(r_type_here).GetProperty(this.gridInventory.Columns[e.ColumnIndex].Name).GetValue(r, null).ToString().ToUpper() == clickedValue.ToUpper()).ToList();

                    if (this.CurrentList != null)
                    {
                        gridInventory.DataSource = this.CurrentList;
                        this.lblRecords.Text = string.Format(@"Total Records: {0}", CurrentList.Count(c => c.ComputerID > 0));
                    }
                }
            }
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, @"error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

r_type_hereあなたの要素の実際のタイプに置き換えるとCurrentList、同じ結果が得られるはずです。

利点:

  • コードが短い
  • コードはより柔軟です。新しい列/プロパティを追加する場合、ここに 1 行のコードを記述する必要はありません。

短所:

  • 文字の大文字と小文字を維持する必要があります。つまり、リスト要素クラスのプロパティ名の大文字と小文字は、対応する列の名前とまったく同じにする必要がありますgridInventory.Columns
  • 読みにくいコード
  • この関数を頻繁に使用すると、パフォーマンスのボトルネックになる可能性があります。通常、リフレクションは case ステートメントよりも遅くなります。

また、プロパティの存在のチェックも同じ LINQwhereステートメントに実装する必要があります。

于 2012-06-14T14:40:15.303 に答える