2022/10/10

C# DataGridViewでLinqを使って列集計

DataGridViewの各列ごとに入力されているセルを数え、その最大値を返すコード。
処理したいDataGridViewをvar dgvとしておきます。

単純にforで書くとこう↓
var count = new int[dgv.ColumnCount]; // int[]型
for(int row = 0; row < dgv.RowCount; row++)
{
  for(int col=0; col < dgv.ColumnCount; col++)
  {
    count[col] += !string.IsNullOrEmpty(dgv[col, row].Value?.ToString()) ? 1 : 0;
  }
}
int maxCount = count.Max();

直感的ですね。
次にLinqで同じことをしてみました↓
int maxCount = dgv.Columns.Cast().Max(col => dgv.Rows.Cast().Count(row => !string.IsNullOrEmpty(row.Cells[col.Index].Value?.ToString())));

自分で書いておきながら(これは暗号だ……)と思い、こんなもん「よく分からないけど動く呪文か何か」にしかならないと思い使用をやめましたが、なんだか勿体なかったのでここに供養することにしました。
コレクション処理を何が何でもLinqで1行で書きたい人は一定数いらっしゃるようなので、そういった方々のお役に立てれば幸いです(?)

(読みにくいコードを書くのは極論あとから読まないアセンブリを書いているのと同義で何のための高級言語か分からなくなるので、ご利用は計画的に…)
2021/04/21

C# で「リソース MaterialDesignTitleTextBlock を解決できません」エラーをどうにかした話

Visual StudioでMaterial Designを使いながらWPFの自社コードをリニューアルしていた時の話。
デバッグ実行し画面を表示させた瞬間にビハインドコードのInitializeComponent()で例外エラーが発生、よく見てみるとXamlのとあるスタイル適応箇所でエラーが発生していました。

↓XAMLの該当箇所
screenshot_210421141153.png
↓発生したエラーメッセージ
screenshot_210421140538.png

当初はMaterial Designの導入の仕方が悪いのかと思い色々ドキュメント等調べながら抜けてる箇所で必要そうな文言を入れたりしてみたのですが変わらず、悩んだ結果辿り着いたのが以下のMaterial Design公式GitHub。

そのうちの一部を抜き出したのが以下。
 MaterialDesignTitleTextBlock => MaterialDesignHeadline6TextBlock
 MaterialDesignHeadlineTextBlock => MaterialDesignHeadline5TextBlock
 MaterialDesignSubheadingTextBlock => MaterialDesignSubtitle1TextBlock
 MaterialDesignDisplay4TextBlock => MaterialDesignHeadline1TextBlock
 MaterialDesignDisplay3TextBlock => MaterialDesignHeadline2TextBlock
 MaterialDesignDisplay2TextBlock => MaterialDesignHeadline3TextBlock
 MaterialDesignDisplay1TextBlock => MaterialDesignHeadline4TextBlock

詰まる所、v3.0.0の変更によってXAML内で使用するStaticResourceなんやらかんやらの文言がまるっきり変更になったみたいです。
しかもこれ、変更後のほうが尚更分かりにくいような気がするのですが… 旧verのDisplay1TextBlockとかもただ番号付けただけって感じで非常に分かりにくいのが更に6まで増えて何がしたいのかよく分かりません。

まぁ解決できたので良いんですが、日本と海外のこういった文字の認識の仕方が違うだけなんですかね?