※ ChatGPTを利用し、要約された質問です(原文:C# ListView 自作列幅調整 描画されない)
C# ListView 自作列幅調整 描画されない
このQ&Aのポイント
C#のListViewでリストビューの列幅を自作し、描画更新されない状態になる問題について質問です。
ListViewに3列追加し幅が変更された際、2列目の幅のみを引き延ばす操作を行うと、描画更新されない状態になります。
サンプルコードと画像が提示されていますが、操作手順によってListViewの描画が正常に表示されない問題が発生しています。
C# ListView 自作列幅調整 描画されない
いつもお世話になっております。
今回はC#のListViewで皆様にお聞きしたいことがあり、
質問させて頂きました。
ListViewに3列追加しListViewの幅が変更された際に
2列目のみを引き延ばすものを作りたいと思っています。
しかし、以下操作を行うと、ListViewのリサイズ等で
描画更新されない状態になってしまいます。
(また、リストアイテムをクリックするとその列は描画されるのですが、
アイテムの描画開始Y位置がおかしくなっています。)
1.縦スクロールバーが表示されるまで縮小する
2.スクロールバーのノブを下に移動
3.縦スクロールバーの表示が消えるまで拡大する
サンプルコード及び画像を添付いたします。
内容は、
3列のListViewに適当なアイテムを10個追加し、
OnClientSizeChangedでClientSize.Widthと1列3列の幅から
2列目の幅を算出・設定しています。
※画像は、以下コントロールをFormに張り付けただけのもので
問題の起こる操作をした際のものになります。
class MyListView : ListView
{
public const int COL_1_WIDTH = 30;
public const int COL_3_WIDTH = 75;
enum LISTVIEW_COL
{
COL1,
COL2,
COL3,
NUM
}
public MyListView() {
Dock = DockStyle.Fill;
HeaderStyle = ColumnHeaderStyle.None;
FullRowSelect = true;
HideSelection = false;
View = System.Windows.Forms.View.Details;
//ヘッダ追加
ColumnHeader column1 = new ColumnHeader();
ColumnHeader column2 = new ColumnHeader();
ColumnHeader column3 = new ColumnHeader();
ColumnHeader[] columnHeaders = { column1, column2, column3 };
this.Columns.AddRange( columnHeaders );
//ヘッダ幅追加
this.Columns[( int )LISTVIEW_COL.COL1].Width = COL_1_WIDTH; //1列固定
this.Columns[( int )LISTVIEW_COL.COL3].Width = COL_3_WIDTH; //3列固定
int width = ClientRectangle.Width;
for( int i = 0; i < Columns.Count; i++ ) {
if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }
width -= Columns[i].Width;
}
//2列 リストビューの幅いっぱいになるように調節
this.Columns[( int )LISTVIEW_COL.COL2].Width = width;
//適当にアイテム追加
for( int i = 0; i < 10; i++ ) {
string[] strs = { "COL1", "COL2", "COL3" };
ListViewItem item = new ListViewItem( strs );
this.Items.Add( item );
}
}
protected override void OnClientSizeChanged( EventArgs e ) {
base.OnClientSizeChanged( e );
//2列の幅を調整
int width = ClientRectangle.Width;
for( int i = 0; i < Columns.Count; i++ ) {
if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }
width -= Columns[i].Width;
}
Columns[( int )LISTVIEW_COL.COL2].Width = width;
}
}
何故このようになってしまうのかご存知の方いらっしゃいましたら教えてください。
お礼
ご回答ありがとうございます。 > ListView の列幅を内部で変更したことによって、コントロールの再描画領域の判定に狂いが生じているのでしょう。 なるほど、確かにクリックした時のリストアイテムのBounds値がおかしな値になっていました。(何故かクリックした時はその行のリストアイテムは描画されました。) > 具体的には、OnClientSizeChanged の最後で this.Refresh(); を実行するようにしましょう。(コントロール内のデータ量があまりにも多い場合などで「チラつき」が発生する可能性があります。その場合は、列幅の変更方法自体を再検討したほうが良いです) 私の環境で表示されるようになりました!ありがとうございます。 (ただ、ちらつきがひどいですが...) 糸口が見えましたので、変更方法を見直してみます! ありがとうございました!