0

実行時に最大 20K 行が作成され、DevExpress GridControl にスローされる DataTable があります。クエリの実行時に最初にチェックされていた 2 つのフィルタリング オプションを追加しました...つまり、オプションを変更したい場合は、この大規模な DataTable を再クエリして再構築し、不要な行を削除する必要がありました。明らかに、これはかなり非効率的で時間がかかりました。DataTable を再構築するのではなく、単純にフィルター処理することで、これを少し改善することにしました。

最初に、私はこの恐ろしいコードの塊を思いつきました:

if (!cheBinObjFolders.Checked)
{
   dt.DefaultView.RowFilter = "File NOT LIKE '*bin*'";
   dt.DefaultView.RowFilter += " AND File NOT LIKE '*obj*'";
   isFiltered = true;
}
else
{
   if (!isFiltered)
   {
      dt.DefaultView.RowFilter = "File <> ''";
      isFiltered = true;
   }

   else
      dt.DefaultView.RowFilter += " AND File <> ''";
}

if (cheNormalFiles.Checked)
{
   if (!isFiltered)
      dt.DefaultView.RowFilter = "Status <> ''";
   else
      dt.DefaultView.RowFilter += " AND Status <> ''";
}

else
{
   if (!isFiltered)
      dt.DefaultView.RowFilter = "Status NOT LIKE '*Normal*'";
   else
      dt.DefaultView.RowFilter += " AND Status NOT LIKE '*Normal*'";
}

だから私はそれを改善したいと思っていました.より多くのフィルタリングオプションが追加された場合は、それをよりクリーンで簡単にします. したがって、チェックボックスの Tag プロパティを列名 (「ファイル」または「ステータス」) に設定すると、チェックボックスはフィルター処理して次のように記述します。

//Empty quotes should be the actual right-hand side of the expression
foreach (Control c in this.Controls)
{
   if (c is CheckEdit)
   {
      if (((CheckEdit)c).Checked && isFiltered)
         dt.DefaultView.RowFilter += c.Tag.ToString() + "";
      else if (((CheckEdit)c).Checked)
      {
         dt.DefaultView.RowFilter = c.Tag.ToString() + "";
         isFiltered = true;
      }
      else
         dt.DefaultView.RowFilter = c.Tag.ToString() + "<> ";
   }
}

しかし、このように式の右辺を動的に考え出す方法がわかりません。私にできることはありますか?この Checkbox コントロールをサブクラス化し、2 つの文字列プロパティを追加する必要があると考えています。「フィールド」と「フィルター」を使用して、フィルターを作成します。より良い方法はありますか?

編集:さて、私はあなたの提案/アドバイスでこれを思いつきました:

    private string BuildTableFilter()
    {
        foreach (Control control in this.Controls)
        {
            if (control is CheckEdit && control.Tag != null)
            {
                var c = (CheckEdit)control;

                if (c.Checked)
                {
                    if (!filters.Contains(c.Tag.ToString()))
                        filters.Add(c.Tag.ToString());
                }
                else
                    filters.Remove(c.Tag.ToString());
            }
        }

        return String.Join(" AND ", filters.ToArray());
    }

したがって、今後行う必要があるのは、適切なフィルター式をタグに追加することだけです。残念ながら、非常に多くの行があるため、UI が短時間 (おそらく 5 秒) ロックされるため、次に取り組む必要があります...

4

1 に答える 1

2

おそらく、ステートメントのリストを使用してクエリを作成する必要があります (この場合、Tag はそのコントロールのフィルター ステートメントになります)。

 var filterTerms = new List<string>();

 foreach (Control c in this.Controls)
 {
     if (c is CheckEdit)
     {
        if (((CheckEdit)c).Checked)
        {
             filterTerms.Add(c.Tag.ToString());
        }
     }
 }

 dt.DefaultView.RowFilter = string.Join(" AND ", filterTerms);
于 2013-10-18T16:01:24.010 に答える